#ifdef IMAM_LOG
#ifndef LOGSYS_FLAG
#define LOGSYS_FLAG
#endif
#endif

#include <project.h>
#define CITI_C

#include <sizes.h>
#include <aclconio.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>    
#include <acldev.h>
#include <aclstr.h>
#include <aclutil.h>
#include <prot8583.h>
#include <define.h>
#include <transact.h>
#include <dbmgr.h>
#include <mdlfuncs.h>
#include <svc.h>
#include <power.h> 
#include <entry.h>  
#include <pinpad.h>   
#include <protocol.h>
#include <packet.h>
#include <tran.h>
#include <comm.h>
#include <modem.h>
#include <ppt.h>
#include <piputl.h>
#include <pipmsg.h>
#include <isoutl.h>
#include <isoload.h>
#include <ifldtbl.h>
#include <msg.h>
#include <msgfuncs.h>
#include <bdt.h>
#include <hdt.h>
#include <trt.h>
#include <mht.h>
#include <iit.h>
#include <accum.h>
#include <form.h>
#include <date.h>
#include <mem.h>
#include <spdebug.h>
#include <funcids.h>
#include <pbatch.h>
#include <errno.h>
#include <ascii.h>
#include <amexhost.h>
#include <pct.h>
#include <formater.h>
#include <table.h>
#include <string.h>
#include <confio.h>
#include <aclfile.h>
#include <format.h>
#include <spamsg.h>
#include <oper.h>
#include <batmsg.h>
#include <ui.h>
#include <tct.h>
#include <multilng.h>
#include <logo.h>
#include <settlbat.h>
#include <msgclrk.h>
#include <msgshf.h>
#include <menufunc.h>
#include <mit.h>
#include <applidl.h>
#include <tblutil.h>
#include <menus.h>
#include <Validt.h>
#include <stats.h>
#include <cardmsg.h>
#include <card.h>
#include <msg.h>
#include <define.h>
#include <entry.h>
#include <pinpad.h>
#include <ctype.h>
#include <gds.h>
#include <power.h>
#include <tip.h>
#include <iso8583.h>
#include <beetle.h>
#include <xmodem.h>
#include <modemmsg.h>
#include <scdefine.h>
#include <rcptsegs.h>
#include <operate.h>
#include <cdt.h>///ivan
#include <battery.h>
#include <printer.h>
#include <rs232.h>
#include <ConfProto.h> //

#include <EMVTags.hpp>
#include <EMVTypeDefs.hpp>
#include <EMVCWrappers.h>
#include <EMVResult.hpp>
#include <Vxemvapdef.h>
#include <mvtfuncs.h>

#include "IMAMids.h"
#include "IMAMsrc.h"
#include "UclCode.h"
#include "ImamUtil.h"
#include "ImamMenu.h"
#include "MiniAtm.h"
#include "ImamWave.h"
#include "ImamMifare.h"
#include "ImamSCard.h"
#include "ImamPinpad.h"
#include "ImamComPort.h"

#include "..\cpacsrc\cpacmsg.h"
#include "..\cpacsrc\cpacids.h"
#include "..\cpacsrc\cpacsrc.h"
#include "..\cpacsrc\cpac.h"
#include "..\cpacsrc\cpacsize.h"
#include "..\cpacsrc\cpacprnt.h"
#include "..\cpacsrc\cpacoper.h"

#include "..\CITIsrc\CITImsg.h"
#include "..\CITIsrc\CITIsrc.h"
#include "..\CITIsrc\CITIids.h"
#include "..\CITIsrc\CITIsize.h"

//#include "..\EPPSrc\EPPSrc.h"
//#include "..\CASHSrc\CASHSrc.h"
//#include "..\CABKSrc\CABKSrc.h"

#include "..\EMVSrc\EMVsrcdef.h"
#include "..\EMVSrc\EMViso.h"

extern ISOLOAD srCITILoadDataFuncs[];
extern unsigned char szEMVField55[EMV_FIELD55_SIZE + 1];
extern VS_BOOL fImamNeedToSendTC; //
extern int	inMAMAvailable;  //
extern VS_BOOL fDisplayIdleMenu;  //
extern int inImamUnlockKeyboard;  // Add
extern int inImamModemLowPower;
unsigned long lnModemTimer = 0L;
 long lnBackLightTimer = 0L;
int inImamLogonNow = 1;		//global var to control logon

extern unsigned long lnGlobalAmount;
int inImamTerminalModel = 0;
int inImamLineNumber = 8;
int inImamMenuLine = 4;
extern char szImamEnterPinLabel[22];
extern char szImamPAN[PAN_SIZE+1];
extern SMenu *ImamActiveMenu;
extern int inImamRestartFlag;
VS_BOOL fImamKeepCommUp = VS_FALSE;
char szMifareData[60];
/*
extern MenuItem	   *pmeScrollItem;
extern int inNoDisp;
extern VS_BOOL fDisplayIdleMenu;
extern int inGlobalMerchantHandle;
extern long lnCPACMiddleCondition;
extern int inGCPACHostSelectedIndex;

extern CPAC_SETTLE_HEADER srCPACSettleHeader;
extern CPAC_SETTLE_MIDDLE srCPACSettleMiddle;
extern CPAC_SETTLE_BOTTOM srCPACSettleBottom;
*/


/*********************************************************************************************
* @func void | vdAddImamFunctions |
*       Adds the CITI specific functions to the function table flexi record.
* @end
**********************************************************************************************/

void vdAddImamFunctions( void )
{
	inAddFunctionPointer( IMAM_INIT, inImamInit); 
	inAddFunctionPointer( IMAM_INIT_UCL_COMM, inImamInitUclComm); 
	inAddFunctionPointer( IMAM_DISPLAY_SIGNAL, inImamDisplaySignalStrength); 
	inAddFunctionPointer( IMAM_WIRELESS_CONNECT, inImamWirelessConnect); 
	inAddFunctionPointer( IMAM_SELECT_COMM, inImamSelectComm); 
	inAddFunctionPointer( IMAM_SET_MASTER_KEY, inImamSetMKey1D);

	inAddFunctionPointer( IMAM_IDLE_LOOP, inImamIdleLoop); 

	inAddFunctionPointer( IMAM_CUST_GET_BASE_AMOUNT, inImamCustGetBaseAmount);
	inAddFunctionPointer( IMAM_CUST_GET_TIP, inImamCustGetTip);

	inAddFunctionPointer( IMAM_CARD_TRX_CHECK, inImamCardTrxCheck);
	inAddFunctionPointer( IMAM_GET_INSTALLMENTS, inImamGetInstallments);
	inAddFunctionPointer( IMAM_GET_TICKET_ID, inImamGetTicketId);
	inAddFunctionPointer( IMAM_EMV_TAG9F02_ADJUST, inImamEmvTag9f02Adjust);
	inAddFunctionPointer( IMAM_EMV_TC_UPLOAD, inImamEmvTcUpload);
	inAddFunctionPointer( IMAM_SET_PARM_DOWN_CONFIG, inImamSetParmDownConfig);
	inAddFunctionPointer( IMAM_SET_FULL_DOWN_CONFIG, inImamSetFullDownConfig);
	inAddFunctionPointer( IMAM_EXIT, inImamExit);
	inAddFunctionPointer( IMAM_EXIT_BY_CANCEL, inImamExitByCancel);
	inAddFunctionPointer( IMAM_CUST_GET_PARTIAL_POINT_AMOUNT, inImamCustGetPartialPointAmount);
	inAddFunctionPointer( IMAM_CUST_SCROLL, inImamCustScroll);
	inAddFunctionPointer( IMAM_SETTLE_ALL_HOST, inImamSettleAllHost);
	inAddFunctionPointer( IMAM_ECHO_ALL_HOST, inImamEchoAllHost);
	inAddFunctionPointer( IMAM_LOGON_ALL_HOST, inImamLogonAllHost);
	inAddFunctionPointer( IMAM_ECHO_ONE_HOST, inImamEchoOneHost);
	inAddFunctionPointer( IMAM_LOGON_ONE_HOST, inImamLogonOneHostOnDemand);
	inAddFunctionPointer( IMAM_SWIPE_CARD_VERIFY, inImamSwipeCardVerify);
	inAddFunctionPointer( IMAM_DUMMY, inImamDummy);
	inAddFunctionPointer( IMAM_FUNCTION, inImamFunction);
	inAddFunctionPointer( IMAM_TEST_PRINT, inImamTestPrint);
	inAddFunctionPointer( IMAM_GET_INV_NUM, inImamGetInvNum);
	inAddFunctionPointer( IMAM_GET_AUTH_CODE, inImamGetAuthCode);
	inAddFunctionPointer( IMAM_SET_AND_CHECK_PRECOMP_VOID, inImamSetAndCheckPrecompVoid);
	inAddFunctionPointer( IMAM_SELECT_MENU, inImamSelectMenu); 
	inAddFunctionPointer( IMAM_PREDIAL, inImamPredial);
	inAddFunctionPointer( IMAM_EMV_GET_BASE_AMOUNT, inImamEMVAPIGetBaseAmount);
	inAddFunctionPointer( IMAM_GET_PRIVATE_LABEL, inImamGetPrivateLabel);
	inAddFunctionPointer( IMAM_GET_CVV2, inImamGetCVV2);
	inAddFunctionPointer( IMAM_KEEP_COMM_UP, inImamKeepCommUp);
	inAddFunctionPointer( IMAM_KEEP_COMM_UP_END, inImamKeepCommUpEnd);
	inAddFunctionPointer( IMAM_KEEP_COMM_UP_END_IDLE, inImamKeepCommUpEndIdle);

	inAddFunctionPointer( PMT_TRX_PURCHASE_FC, inPmtTrxPurchase);// new PIN
	inAddFunctionPointer( PMT_TRX_TRANSFER_FC, inPmtTrxTransfer);// change PIN
	inAddFunctionPointer( PMT_TRX_INFO_SALDO_FC, inPmtTrxInfoSaldo);// echo test
	inAddFunctionPointer( PMT_TRX_MINI_STATEMENT_FC, inPmtTrxMiniStatement);//Sign ON
	inAddFunctionPointer( PMT_TRX_INFO_CDTCARD_FC, inPmtTrxInfoCreditCard);// ib Pin reg

	inAddFunctionPointer( IMAM_EDIT_PCL, inEditPCLOperation);
	inAddFunctionPointer( IMAM_EDIT_CTL, inEditCTLOperation);
	inAddFunctionPointer( IMAM_UPDATE_CTL_PRM, inImamSetContaclessPRM);
	inAddFunctionPointer( IMAM_UPDATE_CTL_MSG, inImamSetContaclessMSG);
	inAddFunctionPointer( IMAM_UPDATE_CTL_CAPK, inImamSetContaclessCAPK);
	inAddFunctionPointer( IMAM_INIT_COM_DEVICE, inImamInitComDevice);
	inAddFunctionPointer( IMAM_SALE_CONTACTLESS, inImamSaleContactless);
	inAddFunctionPointer( IMAM_SALE_CTL_THANKSWELCOME, inImamSaleCTLThanksWelcome);
	inAddFunctionPointer( IMAM_SALE_MIFARE, inImamSaleMifare);
	inAddFunctionPointer( IMAM_SALE_SCARD, inImamSaleSCard);
	inAddFunctionPointer( IMAM_EMV_SEND_REVERSAL, inImamEMVSendReversal);
	inAddFunctionPointer( IMAM_MIFARE_FUNCTION, inImamMifareFunction);
	inAddFunctionPointer( IMAM_SEND_INQUIRY, inImamSendInquiry);
	inAddFunctionPointer( IMAM_SEND_PIGGY_BACK, inImamSendPiggyBack);
	inAddFunctionPointer( IMAM_GET_TDES_PIN, inImamGetTDesPin);
	inAddFunctionPointer( IMAM_SET_TRX_OFFLINE, inImamSetTrxOffline );
	inAddFunctionPointer( IMAM_DOWNLOAD_HOST_LOGO, inImamDownloadHostLogo);
	inAddFunctionPointer( IMAM_SET_MASTER_KEY3D, inImamSetMKey3D); 
	inAddFunctionPointer( IMAM_RESET_TPK, inImamResetTPK); 
	inAddFunctionPointer( IMAM_NEW_TPK, inImamNewTPK); 
	inAddFunctionPointer( IMAM_MAIN_PASS, inImamMainPassword); 
	inAddFunctionPointer( IMAM_PIN_PASS, inImamPinPassword); 
	inAddFunctionPointer(IMAM_SETT_ALL,inSettingAll);
	inAddFunctionPointer(IMAM_SETT_LOCAL_IP, inSettingLocalIp);
	inAddFunctionPointer(IMAM_SETT_LOCAL_SUB,inSettingLocalSub);
	inAddFunctionPointer(IMAM_SETT_LOCAL_GW, inSettingLocalGW);
	inAddFunctionPointer(IMAM_SETT_TID, inSettingLocalTID);
	inAddFunctionPointer(IMAM_SETT_MID, inSettingLocalMID);
	inAddFunctionPointer(IMAM_SETT_DATE, inSettingLocalDate);
	inAddFunctionPointer(IMAM_SETT_HOST_IP, inSettingLocalHostIP);
	inAddFunctionPointer(IMAM_SETT_HOST_PORT, inSettingLocalHostPort);
	inAddFunctionPointer(IMAM_NEW_PIN, inNewPin);
	inAddFunctionPointer(IMAM_CHANGE_PIN, inChangePin);
//	inAddFunctionPointer(IMAM_CHANGE_PIN, inNewPin);
	

	
	
/*	inAddFunctionPointer( IMAM_SET_WORKING_KEY3D, inImamSetWKey3D); */
/*	inAddFunctionPointer( IMAM_SET_MASTER_KEY3D2, inImamSetMKey3D2); */
    inAddFunctionPointer( KRTK_SET_PABX_ME, inKrtkSetPabx); 
	inOverloadFieldID( LOAD_GET_CDT, (PFI_TO) inImamLoadGetCDTIndex); 
	inOverloadFieldID( LOAD_GET_CDT1, (PFI_TO) inImamLoadGetCDTIndex); 

}

/********************************************************************************************* 
* @func int | inTxRx8583 | 
*           This routine will :
*                -> Check to see whether the Carrier has been established.
*                -> If not, wait until carrier is established, till time-out, or abort.
*                -> Send the request packet over the modem port.
*                -> Wait till the response is received at the modem port, or time-out.
*
* @parm int | inModem| 
*       Handle to the Open Modem Device 
* @parm int | inMode|
*       Transmit and Receive OR receive only 
* @parm unsigned char * | pstReqBuf|
*       The address of the source buffer 
* @parm unsigned int | inReqSiz|
*       The size of the request Packet 
* @parm unsigned char * | pstRespBuf|
*       Address of the buffer where the response is stored 
* @parm unsigned int | inRespSiz|
*       Maximum size of response 
* @parm unsigned int |inRespTimeout|
*       Time within which response is to be received 
* @parm unsigned int | inCarrierTimout
*       Time within which carrier is to be establised 
*
* @rdesc return values.
* @flag int    | -> TR_CLR_KEY   Abort while waiting for Carrier.
*                -> TR_WR_FAIL   Write to Modem Failed.
*                -> TR_LOST_CARRIER Carrier Lost while waiting for response.
*                -> TR_TO_RESP   Timeout while waiting for response.
*                -> TR_RD_FAIL   Read from Modem Fail.
*                -> Sucess with the Number of bytes read from the Modem Port.
*
* @end
**********************************************************************************************/
int inImamTxRx8583(int inModem,/* Handle to the Open Modem Device */
    int inMode,/* Transmit and Receive OR receive only */
    unsigned char* pstReqBuf,/* The address of the source buffer */
    unsigned int inReqSiz,/* The size of the request Packet */
    unsigned char* pstRespBuf,/* Address of the buffer where the response is stored */
    unsigned int inRespSiz,/* Maximum size of response */
    unsigned int inRespTimeout,/* Time within which response is to be received */
    unsigned int inCarrierTimout)        /* Time within which carrier is to be establised */ {
    PACKET_OBJECT obPacket;
	unsigned char szSendBuff[1024];
	unsigned char szRecvBuff[1024];
	int inSendSize = 0;
	int inRecvSize = 0;
    int inRetVal = VS_TRUE;                                  /*Check if Carrier is Up */
    VS_BOOL fCarrierPresent = VS_TRUE;
    int inTimeOut;
    char szSourceReversalFileName[20];
    char szDestReversalFielName[20];
	int shUCLType = 0;
	int i = 0;
	int fImamReversal = 0;
	int iRet = 0;
	char stBitmap[17];
	int fImamDuplicateTrx = 0;

  LOG_PRINTFF((0x08L, " inImamTxRx8583  DETECTED"));

	// ASPAC needs to do a reversal even after response is received if
    // powerfail occurs in Analyze response.  EM58250/ASPAC bug # 10,14 & 65
    memset(szSourceReversalFileName, 0x00, sizeof(szSourceReversalFileName));
    vdGetReversalFileName(szSourceReversalFileName, inGetHostIndex());
    sprintf(szDestReversalFielName, "%s%s", szSourceReversalFileName, BACKUP_REV_FILE_EXTN);
    strcat(szSourceReversalFileName, REVERSAL_FILE_EXTN);
/////////////////////////////////////////////////////////////////////////////////////////    

     // kirim reversal fix problem 20080222 

/* Edi from ketut Begin Fix Problem Reversal */
     if(inChkFileExist(szDestReversalFielName) == VS_SUCCESS) 
     {    
          remove(szDestReversalFielName);
     }     

/* End Fix Problem Reversal */
///////////////////////////////////////////////////////////////////////////////////////////


    file_copy(szSourceReversalFileName, szDestReversalFielName);

	//LOG_PRINTFF((0x08L, "srISO.pszField35 = [%s]", srISO.pszField35));
	if ((pstReqBuf[5]==0x04) || //Reversal
		((pstReqBuf[5]==0x02) && (pstReqBuf[15] != 0x00 && pstReqBuf[15] != 0x20))){//All 0200 except SALE and REFUND
		unsigned char isomap1[17];
		int inUnprocPacket = 0;
		int inPacketSize = 0;
		memset(isomap1, 0x00, sizeof(isomap1));
		memset(szSendBuff, 0x00, sizeof(szSendBuff));
		memset(szRecvBuff, 0x00, sizeof(szRecvBuff));
		memcpy(szSendBuff, pstReqBuf, inReqSiz);
		inSendSize = inReqSiz;
		inUnprocPacket = process_8583(1, srBaseIsoFDT, isomap1, szSendBuff, inSendSize);
		if (inUnprocPacket>=0) {
			if ((pstReqBuf[5]==0x04)//Reversal
				){
				LOG_PRINTFF((0x08L, "REVERSAL MESSAGE DETECTED"));
				fImamReversal = 1;
				if ((map_test(isomap1, 35)) || (map_test(isomap1, 45)) || (map_test(isomap1, 52)) || 
					((map_test(isomap1, 55)) && (szEMVField55[1]==0x04))
					){
					map_reset(isomap1, 35);
					map_reset(isomap1, 45);
					map_reset(isomap1, 52);
					if ((map_test(isomap1, 55)) && (szEMVField55[1]==0x04)) map_reset(isomap1, 55);
					memset(szSendBuff, 0x00, sizeof(szSendBuff));
					inPacketSize = process_8583(0, srBaseIsoFDT, isomap1, szSendBuff, sizeof(szSendBuff)-3);
					if (inPacketSize > 0) {
						LOG_PRINTFF((0x08L, "ORIGIN PACKET [%d] to [%d]", inReqSiz, inPacketSize));
						inReqSiz = inPacketSize;
						memcpy(pstReqBuf, szSendBuff, inReqSiz);
					}
				}
/* This is for Indopay-Temporary disable until further test
			} else {  //void of sale/refund for CUP CARD and DEBIT CARD
				if(map_test(isomap1, 52) && map_test(isomap1, 2)) {
					if (strlen((char *)srISO.pszField35)==0) {
						strcpy((char *)srISO.pszField35, "11111111111111111111111111111");
					}
					map_reset(isomap1, 2); 
					map_reset(isomap1, 14);
					map_set(isomap1, 35);
					memset(szSendBuff, 0x00, sizeof(szSendBuff));
					inPacketSize = process_8583(0, srBaseIsoFDT, isomap1, szSendBuff, sizeof(szSendBuff)-3);
					if (inPacketSize > 0) {
						LOG_PRINTFF((0x08L, "ORIGIN PACKET [%d] to [%d]", inReqSiz, inPacketSize));
						inReqSiz = inPacketSize;
						memcpy(pstReqBuf, szSendBuff, inReqSiz);
					}
				}
*/
			}
		}
	}

	if (map_test(stMap8583, 64) ) { //MAC Calculation if field64 exist
		memset(szSendBuff, 0x00, sizeof(szSendBuff));
		memset(szRecvBuff, 0x00, sizeof(szRecvBuff));
		memcpy(szSendBuff, pstReqBuf, inReqSiz);
		inSendSize = inReqSiz;
		LOG_PRINTFF((0x08L, "BEFORE MAC"));
		LOG_PRINT_HEX((unsigned char *)szSendBuff, (int)inSendSize);
	    iRet = inImamComputeMac(szSendBuff, inSendSize);
		LOG_PRINTFF((0x08L, "AFTER MAC"));
		LOG_PRINT_HEX((unsigned char *)szSendBuff, (int)inSendSize);
		memcpy(pstReqBuf, szSendBuff, inReqSiz);
		//if(inResult < 0) return(VS_ERR);
	}
    obPacket.pchSendBuff = pstReqBuf;
    obPacket.inSendSize = inReqSiz;
    obPacket.inReceiveBuffSize = inRespSiz;
    obPacket.pchReceiveBuff = pstRespBuf;
	memset(szSendBuff, 0x00, sizeof(szSendBuff));
	memset(szRecvBuff, 0x00, sizeof(szRecvBuff));
	memcpy(szSendBuff, obPacket.pchSendBuff, obPacket.inSendSize);
	inSendSize = obPacket.inSendSize;
		LOG_PRINT_HEX((unsigned char *)szSendBuff, (int)inSendSize);

	fImamDuplicateTrx = inImamCheckDuplicate(szSendBuff, inSendSize);
#ifdef IMAM_UCL
	shUCLType = inGetCurrentUCLCommLink();
	if (inGetUCLCommLink()) {
		if (shUCLType==IP_COMM || shUCLType==WIFI_COMM ||
			shUCLType==GPRS_COMM || shUCLType==CDMA_COMM) {
			memmove(&szSendBuff[2], szSendBuff, inSendSize);
			szSendBuff[0] = inSendSize/256;
			szSendBuff[1] = inSendSize%256;
			inSendSize = inSendSize + 2;
		}
	}
#endif

	if ((fAES()) && (shUCLType != 0)) { // encrypt data
		unsigned long ticks;
		unsigned char szSendBuffTmp[1024];
		int inSendSizeTmp = inSendSize;
		memset(szSendBuffTmp, 0x00, sizeof(szSendBuffTmp));
		memcpy(szSendBuffTmp, szSendBuff, inSendSize);
		memset(szSendBuff, 0x00, sizeof(szSendBuff));
		ticks = read_ticks();
		iRet = inImamAesEncrypt(szSendBuffTmp, inSendSizeTmp, szSendBuff, &inSendSize);
		memmove(&szSendBuff[2], szSendBuff, inSendSize);
		szSendBuff[0] = inSendSize/256;
		szSendBuff[1] = inSendSize%256;
		inSendSize = inSendSize + 2;
		LOG_PRINTFF((0x08L, "AES Encrypt Time Taken = [%ld ms]", read_ticks()-ticks));
		if (iRet != 0)
			return -1;  //encrypt err
	}

	LOG_PRINTFF((0x08L, "========== START SENDING/RECEIVING ========="));
    if (inMode == TXRX) {
        if (obCommunication.inSend) {
			
            BT_REQUEST_TRACE('B', szSendBuff, inSendSize);
		//inWriteISO8583PacketToLog(obPacket.pchSendBuff, obPacket.inSendSize);
			if (fImamDuplicateTrx){
				inRetVal = inSendSize;
			} else {
				inRetVal = obCommunication.inSend(&obCommunication, (char *)szSendBuff, inSendSize, 
					VS_FALSE, SEND_COMM_TIMEOUT, TRANSMITTING_MSG21);
			}
		
//            inRetVal = obCommunication.inSend(&obCommunication, (char *) obPacket.pchSendBuff, obPacket.inSendSize, VS_FALSE, SEND_COMM_TIMEOUT, TRANSMITTING_MSG21);
			LOG_PRINTFF((0x08L, "inSend RetVal = %d", inRetVal));
            if ((inRetVal == E_NOCARRIER) || (inRetVal == E_X_NOCARRIER) || (inRetVal == VS_CARRIER))
                fCarrierPresent = VS_FALSE;
         	if (inRetVal != inSendSize)
         	{
                pdebug(("inRetVal=%d", inRetVal));
                inRetVal = TR_WR_FAIL;
            }
        }
    }

    inTimeOut = inRespTimeout * 100; /* calc required for ACT library function (xmdm_receive_data)*/     
    if (inRetVal >= 0) {
		LOG_PRINTFF((0x08L, "[SEND (%d)]", inRetVal));
		LOG_PRINT_HEX((unsigned char *)szSendBuff, (int)inSendSize);
		inImamPrintISOPacket(VS_TRUE, szSendBuff , inSendSize);
        if (obCommunication.inReceive)
        {
			if (fImamReversal) {
				inRetVal = obCommunication.inReceive(&obCommunication, (char *)szRecvBuff, inRespSiz, 
					inTimeOut, PROCESSING_REVERSAL_MSG21 /*RECEIVING_MSG21*/);
			} else {
				inRetVal = obCommunication.inReceive(&obCommunication, (char *)szRecvBuff, inRespSiz, 
					inTimeOut, PROCESSING_MSG21 /*RECEIVING_MSG21*/);
			}
			LOG_PRINTFF((0x08L, "inReceive RetVal = %d", inRetVal));
			LOG_PRINTFF((0x08L, "[RECV (%d)]", inRetVal));
			if (inRetVal > 0) {
				BT_RESPONSE_TRACE('B', obPacket.pchReceiveBuff, inRetVal);
				//inWriteISO8583PacketToLog(obPacket.pchReceiveBuff, inRetVal);
				LOG_PRINT_HEX((unsigned char *)szRecvBuff, inRetVal);
				inImamPrintISOPacket(VS_FALSE, szRecvBuff , inRetVal);
				fImamDuplicateTrx = inImamCheckDuplicate(szRecvBuff, inRetVal);
			}
        }
	}

    if (fCarrierPresent == VS_FALSE) {
        pdebug(("!fCarrierPresent"));
        inRetVal = TR_TO_CARRIER;
    } else if ((inRetVal == E_NOCARRIER) || (inRetVal == E_X_NOCARRIER) || (inRetVal == VS_CARRIER)) {
        pdebug(("inRetVal=%d", inRetVal));
        inRetVal = TR_LOST_CARRIER;
    } else if (inRetVal <= 0) {
        pdebug(("TR_TO_RESPONSE"));
        inRetVal = TR_TO_RESPONSE;
    } 
	else 
	{
		if (fAES() && (shUCLType != 0) && (inRetVal>10)) { // decrypt data
			unsigned char szRecvBuffTmp[1024];
			int inRecvSizeTmp = inRetVal-2;   
			memset(szRecvBuffTmp, 0x00, sizeof(szRecvBuffTmp));
			memcpy(szRecvBuffTmp, &szRecvBuff[2], inRecvSizeTmp);
			memset(szRecvBuff, 0x00, sizeof(szRecvBuff));	
			iRet = inImamAesDecrypt(szRecvBuffTmp, inRecvSizeTmp, szRecvBuff, &inRecvSize);
			LOG_PRINTFF((0x08L, "[DECRYPTED (%d)]", inRecvSize));
			LOG_PRINT_HEX((unsigned char *)szRecvBuff, inRecvSize);
			inRetVal = inRecvSize;
			if (iRet != 0)
				return -1;  //decrypt err
		} 
#ifdef IMAM_UCL
		if (inGetUCLCommLink() && (inRetVal>10)) {
			if (shUCLType==IP_COMM || shUCLType==WIFI_COMM ||
				shUCLType==GPRS_COMM || shUCLType==CDMA_COMM) {
				//inRetVal = obPacket.pchReceiveBuff[0]*256 + obPacket.pchReceiveBuff[1]; 
				inRetVal -= 2;
				memmove(szRecvBuff, &szRecvBuff[2], inRetVal);
				inRecvSize = inRetVal;
			}
		}
#endif
		memset(obPacket.pchReceiveBuff, 0x00, sizeof(obPacket.pchReceiveBuff));
		inRecvSize = inRetVal;
		obPacket.inReceiveSize = inRetVal;
		memcpy(obPacket.pchReceiveBuff, szRecvBuff, inRecvSize);

		{
			int inUnprocPacket = 0;
			unsigned char isomap1[17];
			inUnprocPacket = process_8583(1, srBaseIsoFDT, isomap1, obPacket.pchReceiveBuff, inRetVal);
			if (inUnprocPacket>=0) inRetVal=inRetVal-inUnprocPacket;
			LOG_PRINTFF((0x08L, "Kelebihan Packet = %d", inUnprocPacket));
		}
		{
			char buff[17];
			memset(stBitmap, 0x00, sizeof(stBitmap));
			memcpy(stBitmap, &obPacket.pchReceiveBuff[7], 8);
			memset(buff, 0x00,sizeof(buff));
			SVC_HEX_2_DSP((char *)Mti, buff, MTI_SIZE); 
			LOG_PRINTFF((0x08L, "MSG ID = [%s]", buff));
			memset(buff, 0x00,sizeof(buff));
			SVC_HEX_2_DSP(stBitmap, buff, BIT_MAP_SIZE); 
			LOG_PRINTFF((0x08L, "BITMAP = [%s]", buff));
			if (map_test((unsigned char *)stBitmap, 39)) {
				LOG_PRINTFF((0x08L, "BIT 39 = [%s]", srISO.pszField39));
			} 
		}

		{//MAC Validation if field64 exist
			if (map_test((unsigned char *)stBitmap, 64) && fGetImamMacField()) { 
				memset(szRecvBuff, 0x00, sizeof(szRecvBuff));
				memcpy(szRecvBuff, obPacket.pchReceiveBuff, inRetVal);
				iRet = inImamValidateMac(szRecvBuff, inRetVal);
				if(iRet < 0) return(TR_TO_RESPONSE); //or (VS_ERR)
			}
		}

	}
	LOG_PRINTFF((0x08L, "inImamTxRx8583 RetVal = %d", inRetVal));
    LOG_PRINTFF((0x08L, "========== END OF SENDING/RECEIVING ========="));
    return(inRetVal);
}

int inImamCheckDuplicate(unsigned char *szBuff, int inLen)
{
	static unsigned char szStaticBuff[18];
	static unsigned long ulStaticTicks = 0;
	unsigned char szDupBuff[18];
	unsigned long ulTicks = 0;
	unsigned long ulInterval = 2000L;  //2 second interval
	int inRetval = 0;
	memset(szDupBuff, 0x00, sizeof(szDupBuff));
	
	{//Data to compare
		int i=0, j=0;
		szDupBuff[0] = inLen;
		for (j=0;j<(inLen/8)+1; j++){
			for (i=0; i<8; i++){
				if (8*j + i < inLen){
					szDupBuff[i+1] = szDupBuff[i+1] ^ szBuff[8*j+i];  //XOR all message
					szDupBuff[i+1+8] = szDupBuff[i+1+8] + szBuff[8*j+i]; //Add all message
				}
			}
		}
	}
	ulTicks = read_ticks();
	LOG_PRINTFF((0x08L, "DUPLICATE CHECK AT [%ld - %ld] = [%ld]", ulStaticTicks, ulTicks, ulTicks-ulStaticTicks));
	LOG_PRINT_HEX(szDupBuff, sizeof(szDupBuff)-1);

	if ((ulTicks > ulStaticTicks) &&
		(ulTicks < ulStaticTicks + ulInterval) &&
		(memcmp(szStaticBuff, szDupBuff, sizeof(szStaticBuff))==0)
		){
		LOG_PRINTFF((0x08L, "DUPLICATE TRANSMITION"));
		inRetval = 1;
	} else {
		LOG_PRINTFF((0x08L, "NO DUPLICATE TRX"));
		inRetval = 0; 
	}
	memcpy(szStaticBuff, szDupBuff, sizeof(szStaticBuff));
	ulStaticTicks = read_ticks();
	return inRetval;
}

int inImamSetDisplayType (void)
{
	char buff[128];
	{
		memset(buff, 0x00, sizeof(buff));
		SVC_INFO_EPROM(buff);
		LOG_PRINTFF((0x08L, "EPROM = [%s]", buff));
		if (strstr(buff, "Q5") != (char *) NULL) {			//OMNI_3750_ID=="Q5"
			inImamTerminalModel = 3750;
			inImamLineNumber = 8;
			inImamMenuLine = 4;
		} else if (strstr(buff, "QA") != (char *) NULL) {	//#define OMNI_5150_ID  "QA"
			inImamTerminalModel = 510;
			inImamLineNumber = 8;
			inImamMenuLine = 4;
		} else if (strstr(buff, "QB") != (char *) NULL) {	//Vx610
			inImamTerminalModel = 610;
			inImamLineNumber = 8;
			inImamMenuLine = 4;
		} else if (strstr(buff, "QD") != (char *) NULL) {	//Vx670
			inImamTerminalModel = 670;
			inImamLineNumber = 16;
			inImamMenuLine = 6;
		} else if (strstr(buff, "QG") != (char *) NULL) {	//Vx810
			inImamTerminalModel = 810;
			inImamLineNumber = 16;
			inImamMenuLine = 4;
		} else { //Undefined
			inImamTerminalModel = 0;
			inImamLineNumber = 8;
			inImamMenuLine = 4;
			LOG_PRINTFF((0x08L, "UNKNOWN TERMINAL. MIGHT NOT WORK PROPERLY..."));
		} 
	}
	return VS_SUCCESS;
}

/////// ADDITIONAL FUNCTION ///////////
///////////////////////////////////////
int inImamInit (TRANSACTION_OBJECT *pobTran) //
{
	char buff[128];
	unsigned long ticks;

	LOG_INIT("SOFTPAY",LOGSYS_COMM,0xFFFFFFFF);
	LOG_PRINTFF((0x08L, "IMAM LOG STARTED"));

	inImamSetDisplayType();
	{//Power Save Management
		memset(buff, 0x00, sizeof(buff));
		get_env_x("POWERSAVE", 0, buff);
		lnBackLightTimer = atol(buff) * 1000L;
		if ((0<=lnBackLightTimer ) && (lnBackLightTimer<120000L)){
			lnBackLightTimer = 120000L;
		}

		memset(buff, 0x00, sizeof(buff));
		get_env_x("POWERSAVE", 1, buff);
		if (atol(buff)==0L) {
			lnModemTimer = 0L;
		} else {
			lnModemTimer = (atol(buff) * 1000L);// + lnBackLightTimer;
		}

		memset(buff, 0x00, sizeof(buff));
		get_env_x("POWERSAVE", 2, buff);
		if (strlen(buff)==0) {
			strcpy(buff, "3000");
		} else {
			strcat(buff, "000");
		}
		put_env("*POW", buff, strlen(buff));

		memset(buff, 0x00, sizeof(buff));
		get_env_x("POWERSAVE", 3, buff);
		if (strlen(buff)==0) {
			strcpy(buff, "120");	
		} 
		put_env("*OFF", buff, strlen(buff));
	}

	memset(buff, 0x00, sizeof(buff));
	get_env_x("#CZE", 0, buff);
	if (atoi(buff) != 1) {
		inImamRecountMenu();
		vdImamDisplayMenu(0);
		return (VS_SUCCESS);
	}

	ticks = read_ticks();
	LOG_PRINTFF((0x08L, "IMAM INIT CONFIGURATION..."));

	//
	#ifndef IMAM_REMOVE_BATCH_MINIATM
	   CreateBatchRecord();
	#endif

//CreateDBSRecord();
	
	if (inImamInitHostConfig(pobTran)==(VS_ERROR)) {
		DisplayStatus("Configurasi Error");
		vdWarnBeep();
		SVC_WAIT(5000);
		vdWarnBeep();
		return (VS_ERROR);
	}

	if (inImamInitOthers(pobTran)==(VS_ERROR)) {
		DisplayStatus("Configurasi Error");
		vdWarnBeep();
		SVC_WAIT(5000);
		vdWarnBeep();
		return (VS_ERROR);
	}

	LOG_PRINTFF((0x08L, "IMAM INIT CONFIGURATION...OK"));
	LOG_PRINTFF((0x08L, "TIME TAKEN [%ld ms]", read_ticks()-ticks));
	return (VS_SUCCESS);
}

#if 0 // imam for next Season
int Letmapcpac(CPAC_REC * rec, int start, int Len)
{
  int i=0;
   int check =0;
   int buflen=0;
   buflen=Len;
  for (i=0;i<16;i++)
  	{ 
  	    if ((i==start) && (buflen>0))
			check=1;		
	    else
		check=0;		
		
		switch (i)
		{
		 case 0:
		 	rec->fUnused1=check;
			break;
		 case 1:	
		 	rec->fUnused2=check;
			break; 	
		 case 2:	
		 	rec->fUnused3=check;
			break; 	
		 case 3:	
		 	rec->fUnused4=check;
			break; 	
		 case 4:	
		 	rec->fUnused5=check;
			break; 	
		case 5:	
		 	rec->fUnused6=check;
			break; 	
		case 6:	
		 	rec->fUnused7=check;
			break; 	
		case 7:	
		 	rec->fUnused8=check;
			break; 	
		case 8:	
		 	rec->fUnused9=check;
			break; 	
	     case 9:	
		 	rec->fUnused10=check;
			break; 	
		case 10:	
		 	rec->fUnused11=check;
			break; 	
		 case 11:	
		 	rec->fUnused12=check;
			break; 	
		 case 12:	
		 	rec->fUnused13=check;
			break; 	
		 case 13:	
		 	rec->fUnused14=check;
			break; 	
		 case 14:	
		 	rec->fUnused15=check;
			break; 	
		 case 15:	
		 	rec->fUnused16=check;
			break; 	

		}

		buflen--;
		
  	}  
  
}
#endif

int inImamInitHostConfig(TRANSACTION_OBJECT *pobTran)
{
	char buff[128];
	char szParam[128];
	int inHostTotNum = 0;
	int i = 0;
	int inCardCount = 0;
	int j=0;
	int inIssuerCount=0;
	int k=0;
	int inleniss=0;
	

	{//save HDT, CDT, CPT if not exist
		int inRetCopy;
		

		inRetCopy = file_copy("hdt.dat", "hdt_org.dat");
		inRetCopy = file_copy("cpt.dat", "cpt_org.dat");
		inRetCopy = file_copy("cdt.dat", "cdt_org.dat");
	//	inRetCopy = file_copy("iit.dat", "iit_org.dat");// imam 
		inRetCopy = remove("hdt.dat");
		inRetCopy = remove("cpt.dat");
		inRetCopy = remove("cdt.dat");
		//inRetCopy = remove("iit.dat");
		inRetCopy = file_copy("hdt_org.dat", "hdt.dat");
		inRetCopy = file_copy("cpt_org.dat", "cpt.dat");
		inRetCopy = file_copy("cdt_org.dat", "cdt.dat");		
	//	inRetCopy = file_copy("iit_org.dat", "iit.dat");		
		if (inRetCopy < 0) return (VS_ERR);
		for (i=0; i<6; i++) {
			memset(szParam, 0x00, sizeof(szParam));
			sprintf(szParam, "CPT%d-PRI", i+1);
			put_env(szParam, "", 0);
			sprintf(szParam, "CPT%d-SEC", i+1);
			put_env(szParam, "", 0);
			sprintf(szParam, "CPT%d-RTO", i+1);
			put_env(szParam, "", 0);
			sprintf(szParam, "CPT%d-STP", i+1);
			put_env(szParam, "", 0);
			sprintf(szParam, "CPT%d-STS", i+1);
			put_env(szParam, "", 0);
		}
	}

	memset(buff, 0x00, sizeof(buff));
	get_env_x("HOST.TOTAL", 0, buff);
	inHostTotNum = atoi(buff);
	if (inHostTotNum <=0) inHostTotNum = 1;
	if (inHostTotNum >=6) inHostTotNum = 6;
	
	LOG_PRINTFF((0x08L, "Number of Host = [%d]", inHostTotNum));

	for (i=0; i<inHostTotNum; i++) {
		inLoadHDTRec(0);  //as default host

		vdSetHostGroupRef(i);	//Host Group Ref

		memset(buff, 0x00, sizeof(buff));
		sprintf(buff, "HST%d", (i + 1));
		LOG_PRINTFF((0x08L, "Host File Name: [%s]", buff));
		if (strlen(buff)) vdSetHostFileName(buff);							//Host File Name

		memset(szParam, 0x00, sizeof(szParam));
		sprintf(szParam, "HOST.%d.ID", i+1);
		memset(buff, 0x00, sizeof(buff));
		if (get_env_x(szParam, 0, buff)<=6) return (VS_ERROR);  //error detected
		buff[10] = 0x00;
		if (strlen(buff)) vdSetHostName(buff);                                 //Host Name

		memset(buff, 0x00, sizeof(buff));
		get_env_x(szParam, 3, buff);
		vdSetImamEchoTest(atoi(buff));
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szParam, 4, buff);
		vdSetImamNeedLogon(atoi(buff));
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szParam, 5, buff);
		vdSetImamVoidSwipePin(atoi(buff));
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szParam, 6, buff);
		vdSetImamRefundApprCode(atoi(buff));
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szParam, 7, buff);
		vdSetImamEmvHost(atoi(buff));
		memset(buff, 0x00, sizeof(buff));
		get_env_x("EMV.ALLOWED", 0, buff);
		if (atoi(buff)==0) vdSetImamEmvHost(0);
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szParam, 8, buff);
		vdSetImamGuestHost(atoi(buff));
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szParam, 9, buff);
		vdSetImamHostPiggyBack(atoi(buff));
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szParam, 10, buff);
		vdSetImamHostOffineRefund(atoi(buff));
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szParam, 11, buff);
		vdSetImamHostOfflineVoid(atoi(buff));
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szParam, 12, buff);
		vdSetImamHostTrack1Req(atoi(buff));
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szParam, 13, buff);
		buff[12] = 0x00;
		if (strlen(buff)) vdSetLGOFileName(buff);                   

		memset(buff, 0x00, sizeof(buff));
		get_env_x(szParam, 1, buff);
		vdSetCurrencyIdx(atoi(buff));						 //HDT Currency Index
		if (atoi(buff)==0) {
			vdSetAmountFormat("CCCnnnn,nnn,nnN");            //Amount Format Rupiah
		} else {
			vdSetAmountFormat("CCCnnnnn,nnN.NN");
		}

		{
			CPAC_REC srCPAC;
			char szHostParam[128];
			char szTPDU[20];
			char szHostFileName[20];

			memset(szHostParam, 0x00, sizeof(szHostParam));
			//memset((char *)srCPAC, 0x00, sizeof(CPAC_REC));
			memset(szHostFileName, 0x00, sizeof(szHostFileName));

			sprintf(szHostFileName, "HST%d.dat", i+1);
			inLoadConfRec(szHostFileName, REC_SIZEOF(CPAC_REC), 0, (char *)&srCPAC);
			
			sprintf(szHostParam, "H%d-MAX", i+1);
			if (atoi(buff)==0) {
				put_env(szHostParam, "9", 1);					//Amount Max Digit
				srCPAC.inMaxAmtEntryDigits = 9;
			} else {
				put_env(szHostParam, "8", 1); 
				srCPAC.inMaxAmtEntryDigits = 8;
			}
			memset(buff, 0x00, sizeof(buff));
			get_env_x(szParam, 2, buff);
			buff[3]=0x00;
			memset(szHostParam, 0x00, sizeof(szHostParam));
			sprintf(szHostParam, "H%d-NII", i+1);
			put_env(szHostParam, buff, strlen(buff));						 //NII
			strcpy(srCPAC.szCPACNII, buff);

			memset(szTPDU, 0x00, sizeof(szTPDU));
			sprintf(szTPDU, "600%s80EC", buff);
			memset(szHostParam, 0x00, sizeof(szHostParam));
			sprintf(szHostParam, "H%d-TPDU", i+1);
			put_env(szHostParam, szTPDU, 10);						 //TPDU
			strcpy(srCPAC.szCPACTPDU, szTPDU);

			memset(szParam, 0x00, sizeof(szParam));
			sprintf(szParam, "HOST.%d.TERMINAL", i+1);
			memset(buff, 0x00, sizeof(buff));
			if (get_env_x(szParam, 0, buff)<=2) 
				return (VS_ERROR);
			buff[8] = 0x00;
			memset(szHostParam, 0x00, sizeof(szHostParam));
			sprintf(szHostParam, "H%d-TID", i+1);
			put_env(szHostParam, buff, strlen(buff));               //TID
			strcpy(srCPAC.szCPACTID, buff);

			memset(buff, 0x00, sizeof(buff));
			get_env_x(szParam, 1, buff);
			buff[15] = 0x00;
			memset(szHostParam, 0x00, sizeof(szHostParam));
			sprintf(szHostParam, "H%d-MID", i+1);
			put_env(szHostParam, buff, strlen(buff));				//MID
			strcpy(srCPAC.szCPACMID, buff);
			// imam 
			memset(szHostParam, 0x00, sizeof(szHostParam));
			sprintf(szHostParam,"HOST.%d.TMIDMASK", i+1);
			memset(buff, 0x00, sizeof(buff));
			get_env_x(szHostParam, 0, buff);
			srCPAC.fMaskMid = atoi(buff);
			memset(buff, 0x00, sizeof(buff));
			get_env_x(szHostParam, 1, buff);
			srCPAC.fMaskTid= atoi(buff);

			memset(szHostParam, 0x00, sizeof(szHostParam));
			sprintf(szHostParam,"HOST.%d.MERCH", i+1);
			memset(buff, 0x00, sizeof(buff));
			get_env_x(szHostParam, 0, buff);
			srCPAC.fMerchEnable= atoi(buff);
			
/*
			memset(szHostParam, 0x00, sizeof(szHostParam));
			sprintf(szHostParam,"HOST.%d.PANMASK", i+1);
			memset(buff, 0x00, sizeof(buff));
			get_env_x(szHostParam, 0, buff);
			panstart = atoi(buff);
			memset(buff, 0x00, sizeof(buff));
			get_env_x(szHostParam, 1, buff);
			panlen= atoi(buff);
			Letmapcpac(&srCPAC,panstart,panlen);
			for future
	*/				
			

			/****  load masking from config ****/
			memset(szHostParam, 0x00, sizeof(szHostParam));
			strcpy(szHostParam, "PANMASK");
			memset(buff, 0x00, sizeof(buff));
			get_env_x(szHostParam, 0, buff);
			srCPAC.fMaskPANinCRcpt = atoi(buff);
			memset(buff, 0x00, sizeof(buff));
			get_env_x(szHostParam, 1, buff);
			srCPAC.fMaskPANinMRcpt = atoi(buff);
			memset(buff, 0x00, sizeof(buff));
			get_env_x(szHostParam, 2, buff);
			srCPAC.fMaskPANinBRcpt = atoi(buff);
			/*****************************************/
			
			
			inSaveConfRec (szHostFileName, REC_SIZEOF(CPAC_REC), 0, (char *)&srCPAC);
		}

		vdSetBatchIndex(i);									//important and must to separate the batch

		vdSetCommunicationIndex(i);
		{
			char szCPTParam[128];
			inLoadCPTRec(0);   //as default

			memset(szParam, 0x00, sizeof(szParam));
			sprintf(szParam, "HOST.%d.COMM", i+1);
			memset(buff, 0x00, sizeof(buff));
			if (get_env_x(szParam, 0, buff)<=4) 
				return (VS_ERROR);  
			memset(szCPTParam, 0x00, sizeof(szCPTParam));
			sprintf(szCPTParam, "CPT%d-PRI", i+1);
			if (buff[0] != 'T') {
				memmove(&buff[1], buff, strlen(buff));
				buff[0] = 'T';
			}
			put_env(szCPTParam, buff, strlen(buff));          //Primary Phone
			sprintf(szCPTParam, "CPT%d-STP", i+1);
			put_env(szCPTParam, buff, strlen(buff));          //Settle Primary Phone

			memset(buff, 0x00, sizeof(buff));
			get_env_x(szParam, 1, buff);
			memset(szCPTParam, 0x00, sizeof(szCPTParam));
			sprintf(szCPTParam, "CPT%d-SEC", i+1);
			if (buff[0] != 'T') {
				memmove(&buff[1], buff, strlen(buff));
				buff[0] = 'T';
			}
			put_env(szCPTParam, buff, strlen(buff));          //Secondary Phone
			sprintf(szCPTParam, "CPT%d-STS", i+1);
			put_env(szCPTParam, buff, strlen(buff));          //Settle Secondary Phone
                // imam add 19 juni 2011
                
				   
			memset(buff, 0x00, sizeof(buff));
			get_env_x(szParam, 2, buff);
			memset(szCPTParam, 0x00, sizeof(szCPTParam));
			sprintf(szCPTParam, "CPT%d-RTO", i+1);
			put_env(szCPTParam, buff, strlen(buff));          //Response Time Out

                     // add carrier time out
			 memset(buff, 0x00, sizeof(buff));
			get_env_x(szParam, 3, buff);
			memset(szCPTParam, 0x00, sizeof(szCPTParam));
			sprintf(szCPTParam, "CPT%d-CTO", i+1);
			 if (atoi(buff)==0)
			 	sprintf(buff,"%d",30);
			 
			put_env(szCPTParam, buff, strlen(buff));          //Response Time Out 
  
			memset(szParam, 0x00, sizeof(szParam));
			sprintf(szParam, "HOST.%d.SETTLE", i+1);
			memset(buff, 0x00, sizeof(buff));
			if (get_env_x(szParam, 0, buff)>=4) {
				memset(szCPTParam, 0x00, sizeof(szCPTParam));
				sprintf(szCPTParam, "CPT%d-STP", i+1);
				if (buff[0] != 'T') {
					memmove(&buff[1], buff, strlen(buff));
					buff[0] = 'T';
				}
			}
			if (strlen(buff)>1) put_env(szCPTParam, buff, strlen(buff));          //Settle Primary Phone

			memset(buff, 0x00, sizeof(buff));
			if (get_env_x(szParam, 1, buff)>=4) {
				memset(szCPTParam, 0x00, sizeof(szCPTParam));
				sprintf(szCPTParam, "CPT%d-STS", i+1);
				if (buff[0] != 'T') {
					memmove(&buff[1], buff, strlen(buff));
					buff[0] = 'T';
				}
			}
			if (strlen(buff)>1) put_env(szCPTParam, buff, strlen(buff));          //Settle Secondary Phone

			inSaveCPTRec(i);
		}
		{
			inLoadDCTRec(i);  //one to one record
			memset(szParam, 0x00, sizeof(szParam));
			sprintf(szParam, "HOST.%d.PINKEY", i+1);
			memset(buff, 0x00, sizeof(buff));
			if (get_env_x(szParam, 0, buff)<= 4) return (VS_ERROR);
			buff[16] = 0x00;
			if (strlen(buff)) vdSetPINKey(buff);

			memset(buff, 0x00, sizeof(buff));
			get_env_x(szParam, 1, buff);
			vdSetMinPINDigit(atoi(buff));
			memset(buff, 0x00, sizeof(buff));
			get_env_x(szParam, 2, buff);
			vdSetMaxPINDigit(atoi(buff));
/* 
			NO NEED LEAVE IT TO HOST ID
			memset(buff, 0x00, sizeof(buff));
			get_env_x(szParam, 4, buff);
			if (atoi(buff)<=0) buff[0] = '0';
			vdSetMasterKeyAddress(buff[0]);
*/
			inSaveDCTRec(i);

			memset(buff, 0x00, sizeof(buff));
			get_env_x(szParam, 3, buff);
			vdSetImamMacField(atoi(buff));
		}
		inSaveHDTRec(i);
	}

	for (j=0; j<20; j++) {  //card max 20 per host
		for (i=0; i<inHostTotNum; i++) { //host
			int inLen = 0;
			inLoadHDTRec(i);
			inLoadCDTRec(0);
			memset(szParam, 0x00, sizeof(szParam));
			sprintf(szParam, "HOST.%d.CARD.%d", i+1, j+1);
			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 0, buff);
			if ((inLen>0 && inLen<33)) return (VS_ERROR);
			if (inLen==0) continue;
			buff[10] = 0x00;
			if (strlen(buff)) vdSetCardLabel(buff);
			vdSetHostIndex(i);
			vdSetHostGroupID(i);

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 1, buff);
			buff[2] = 0x00;
			if (strlen(buff)) vdSetCardAbbrev(buff);

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 2, buff);
			vdSetType(atoi(buff));
			if (atoi(buff)==DEBIT_CARD) {
				vdSetPinpadRequired(VS_TRUE);
			} else {
				vdSetPinpadRequired(VS_FALSE);
			}
			vdSetChkServiceCode(fGetImamEmvHost());

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 3, buff);
			vdSetIssuerNum(atoi(buff));

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 4, buff);
			if (strlen(buff)) vdSetPANLo(buff);

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 5, buff);
			if (strlen(buff)) vdSetPANHi(buff);

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 6, buff);
			vdSetMinPANDigit(atoi(buff));

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 7, buff);
			vdSetMaxPANDigit(atoi(buff));

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 8, buff);
			vdSetCVV_II(atoi(buff));

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 9, buff);
			vdSetImamSwipe4DBC(atoi(buff));

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 10, buff);
			vdSetImamManual4DBC(atoi(buff));

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 11, buff);
			vdSetChkLuhn(atoi(buff));

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 12, buff);
			vdSetExpDtReqd(atoi(buff));
		
			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 13, buff);
			vdSetImamSelectAcc(atoi(buff));

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 14, buff);
			vdSetImamPrivateLabel(atoi(buff));

			//TRX IS HERE

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 16, buff);
			vdSetManEntry(atoi(buff));
			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x("TRX.MANUAL", 0, buff);
			if (atoi(buff)==0) vdSetManEntry(0);

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 17, buff);
			vdSetPaymentIndex(atoi(buff));

			if ((fImamSSP()==0) && (fImamOR()==0)) {
				vdSetPaymentIndex(0);
			}
			//memset(buff, 0x00, sizeof(buff));
			//inLen = get_env_x("TRX.SSP", 0, buff);
			//if (atoi(buff)==0) vdSetPaymentIndex(0);

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 18, buff);
			vdSetCDTSale(atoi(buff));
			if (!fImamSale()) vdSetCDTSale(0);
			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 19, buff); //for CardVer, PreAuth, and AuthOnly
			vdSetCDTCardVer(atoi(buff));
			vdSetCDTAuthOnly(atoi(buff));
			vdSetCDTNormPreAuth(atoi(buff));
			if (!fImamCardVer()) vdSetCDTCardVer(0);
			if (!fImamAuthOnly()) vdSetCDTAuthOnly(0);
			if (!fImamNormPreAuth()) vdSetCDTNormPreAuth(0);
			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 20, buff);
			vdSetCDTOffline(atoi(buff));
			if (!fImamOffline()) vdSetCDTOffline(0);
			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 21, buff);
			vdSetCDTRefund(atoi(buff));
			if (!fImamRefund()) vdSetCDTRefund(0);
			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 22, buff);
			vdSetCDTTipAdjust(atoi(buff));
			if (!fImamTipAdjust()) vdSetCDTTipAdjust(0);

			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 23, buff);
			vdSetCDTPreAuth(atoi(buff));
			if (!fImamPreAuth()) vdSetCDTPreAuth(0);
			memset(buff, 0x00, sizeof(buff));
			inLen = get_env_x(szParam, 24, buff);
			vdSetCDTPreComp(atoi(buff));
			if (!fImamPreComp()) vdSetCDTPreComp(0);

			vdSetImamCDTIndex(inCardCount);
			inSaveCDTRec(inCardCount);
			inCardCount++;
		}
	}
	

#if 0
//imam Edit the Issuer Here
   memset(buff, 0x00, sizeof(buff));
   get_env_x("ISSUER.TOTAL", 0, buff);
   inIssuerCount= atoi(buff);
   if (inIssuerCount>=20) inIssuerCount= 20;

    for (k=0; k<inIssuerCount; k++) { 
	inLoadIITRec(k);
	memset(szParam, 0x00, sizeof(szParam));
	
	//vdSetIssuerNumber(k);

	sprintf(szParam, "ISSUER.%d.TAG",k);
	memset(buff, 0x00, sizeof(buff));	
	inleniss = get_env_x(szParam, 0, buff);
	if (inleniss==0) continue;
   	vdSetIssuerAbbrev((buff));
   
	memset(buff, 0x00, sizeof(buff));
	inleniss = get_env_x(szParam, 1, buff);
	vdSetIssuerLabel((buff));
	
       memset(buff, 0x00, sizeof(buff));
	inleniss  = get_env_x(szParam, 2, buff);
	vdSetPANFormat((buff));

	memset(buff, 0x00, sizeof(buff));
	inleniss  = get_env_x(szParam, 3, buff);
	vdSetMerchExpDate(atoi(buff));
	
	
	
	memset(buff, 0x00, sizeof(buff));
	inleniss  = get_env_x(szParam, 4, buff);
	vdSetCustExpDate(atoi(buff));

	memset(buff, 0x00, sizeof(buff));
	inleniss  = get_env_x(szParam, 5, buff);
	vdSetMerchPANFormat(atoi(buff));

	inSaveIITRec(k);


	}
#endif


	{ //EMV for EST, MVT
		for (i=0;i<4;i++){
			inLoadMVTRec(i);
			memset(buff, 0x00, sizeof(buff));
			get_env_x("EMV.FLOORLIMIT", 0, buff);
			vdSetEMVFloorLimit(atol(buff));
			vdSetFallbackAllowedFlag(inImamEMVFallback());
			inSaveMVTRec(i);
		}
	}
	return (VS_SUCCESS);
}

int inImamInitOthers(TRANSACTION_OBJECT *pobTran)
{
	int inRetval = VS_SUCCESS;
	char buff[128];

	if (inLoadTCTRec(0) == VS_SUCCESS){//Tip Processing should be always on  ==>(0==OFF)(1==prompt)(2==ON but noprompt)
		if (fImamTipAdjust() && fImamTipPrompt()==0) {  //Permata Style
			vdSetTipProcessing(2);  
		} else if (fImamTipPrompt()){
			vdSetTipProcessing(1);
		} else {
			vdSetTipProcessing(0);
		}
		LOG_PRINTFF((0x08L, "TIP Processing = [%d]", inGetTipProcessing()));

		memset(buff, 0x00, sizeof(buff));
		get_env_x("PWD.USER", 0, buff);
		if (strlen(buff)) vdSetSuperPwd(buff);

		memset(buff, 0x00, sizeof(buff));
		get_env_x("PWD.ADMIN", 0, buff);
		if (strlen(buff)) vdSetManagerPwd(buff);

		memset(buff, 0x00, sizeof(buff));
		get_env_x("TRX.FORCE-SETTLE", 0, buff);
		vdSetImamForceSettle(atoi(buff));

		memset(buff, 0x00, sizeof(buff));
		get_env_x("TRX.REFERRAL", 0, buff);
		vdSetImamReferral(atoi(buff));

		memset(buff, 0x00, sizeof(buff));
		get_env_x("TRX.PINBASED", 0, buff);
		vdSetDebitFlag(atoi(buff));
		if (atoi(buff)){
			vdSetPINPadType(4);
		} else {
			vdSetPINPadType(0);
		}
#ifndef __arm
		if (inImamGetCom2Device()>0){
			vdSetPINPadType(0);
			vdSetDebitFlag(0);
		}
#endif
		memset(buff, 0x00, sizeof(buff));
		get_env_x("TRX.AIRLINE", 0, buff);
		vdSetImamAirlineTrx(atoi(buff));
		inUpdateTCTRec();
	}
	{
		strcpy(szImamEnterPinLabel, "");
		strcpy(szImamPAN, "");
	}
LOG_PRINTFF((0x08L, "LOAD UCL= [%d]",inLoadPCLRec(0)  ));

	if (inLoadPCLRec(0) == VS_SUCCESS){
		char szVar[30];
		strcpy(szVar, "UCL.COMM");
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 0, buff);
		vdSetImamUCLComm(atoi(buff));

		strcpy(szVar, "UCL.PRI-HOSTIP");
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 0, buff);
		if (strlen(buff)) vdSetImamPriHostIP(buff);
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 1, buff);
		vdSetImamPriPort(atoi(buff));

		strcpy(szVar, "UCL.SEC-HOSTIP");
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 0, buff);
		if (strlen(buff)) vdSetImamSecHostIP(buff);
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 1, buff);
		vdSetImamSecPort(atoi(buff));

		strcpy(szVar, "UCL.LOCALIP");
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 0, buff);
		if (strlen(buff)) vdSetImamLocalIP(buff);
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 1, buff);
		if (strlen(buff)) vdSetImamSubnet(buff);
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 2, buff);
		if (strlen(buff)) vdSetImamGateway(buff);

		strcpy(szVar, "UCL.PPPAUTH");
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 0, buff);
		vdSetImamPPPAuth(atoi(buff));

		strcpy(szVar, "UCL.PARAM");
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 0, buff);
		vdSetImamIdleConnectTime(atoi(buff));
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 1, buff);
		vdSetImamKeepAliveTimer(atoi(buff));
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 2, buff);
		vdSetImamFirstSocketTimeOut(atoi(buff));

		strcpy(szVar, "UCL.ENCRYPT");
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 0, buff);
		vdSetImamEncryptType(atoi(buff));

		strcpy(szVar, "UCL.SPACC");
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 0, buff);
		vdSetImamUCLUserName(buff);
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 1, buff);
		vdSetImamUCLPassword(buff);

		strcpy(szVar, "UCL.GPRS");
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 0, buff);
		if (strlen(buff)) vdSetImamGPRSDialNo(buff);
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 1, buff);
		if (strlen(buff)) vdSetImamGPRSAPN(buff);

		strcpy(szVar, "UCL.WIFI");
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 0, buff);
		vdSetImamWiFiChannel(atoi(buff));
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 1, buff);
		if (strlen(buff)) vdSetImamWiFiSysID(buff);
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 2, buff);
		vdSetImamWiFiWEPMode(atoi(buff));
		memset(buff, 0x00, sizeof(buff));
		get_env_x(szVar, 3, buff);
		if (strlen(buff)) vdSetImamWiFiWEPKeyValue(buff);

		inUpdatePCLRec();
	}

	inImamRecountMenu();
	vdImamDisplayMenu(0);
	return (VS_SUCCESS);
}

int inImamInitUclComm (TRANSACTION_OBJECT *pobTran)
{
	int inRetVal = VS_SUCCESS;
#ifdef IMAM_UCL
	int inRet = 0;
	short shCommLink = 0;
	static unsigned int inInitUclCount = 0;
	
	shCommLink = inGetUCLCommLink();
	inInitUclCount++;

	LOG_PRINTFF((0x08L, "[%d] INIT UCL COMM : %d", inInitUclCount, shCommLink));

	if (shCommLink) {
		//inRet = rename("F:DIALER.OUT", "DIALER2.OUT");
		//inRet = remove("F:DIALER.OUT");
		//LOG_PRINTFF((0x08L, "F:DIALER.OUT Removing RetVal = %d", inRet));
		//if (inRet==0) return (VS_ERR);  //let softpay restart and reclaiming it's flash memory
	} 

	if (shCommLink<1 || shCommLink>7) {
		//Invalid Number but still ok, use current comm
		DisplayStatus("COMM: Normal Modem");
		LOG_PRINTFF((0x08L, "COMM: Normal Modem"));
		SVC_WAIT(200);
		{
  			vdSetMenuFont();
			fDisplayLogoNow = VS_TRUE;
			vdSelectMenu(ROOT_MENU_ID);
			enable_hot_key();
		}
		return VS_SUCCESS;
	}
	inImamReleaseComm();
	clrscr();
	LOG_PRINTFF((0x08L, "Init UCL, CommLink = %d", shCommLink));
	obCommunication.inLinkType = 4;   //must be one
	//obCommunication.inLinkType = 4;   //must be one
	
    vdInitializeUclComm (&obCommunication);
    inRetVal = obCommunication.inInitialize (&obCommunication); //Temp disabled
	{
  		vdSetMenuFont();
		fDisplayLogoNow = VS_TRUE;
		vdSelectMenu(ROOT_MENU_ID);
		enable_hot_key();
	}
#endif

	return ( inRetVal );
}

int inImamInitUclCommEx(void)
{
	TRANSACTION_OBJECT obTran;
	disable_hot_key();
	return inImamInitUclComm(&obTran);
}

int inimamsetEthernet(void)
{  
         DisplayStatus("Release comm...");
	inImamReleaseComm();
	inLoadPCLRec(0);
	vdSetImamUCLComm(4);
	SVC_WAIT(2000);
	DisplayStatus("Init new comm...");
	inUpdatePCLRec();
	inImamInitUclCommEx();
		return VS_SUCCESS;
		
}

int inImamReleaseComm(void)
{
	LOG_PRINTFF((0x08L, "--inImamReleaseComm--"));
	//{
	//	LOG_PRINTFF((0x08L, "DISABLED TEMP obCommunication.inLinkType = [%d]", obCommunication.inLinkType));
	//	return 1;
	//}
	if (obCommunication.inLinkType == NO_COMM) return 1;

	if (obCommunication.inEnd){
		obCommunication.inEnd(&obCommunication);
	}
	if (obCommunication.inDeinitialize){
		obCommunication.inDeinitialize(&obCommunication);   
    }
	obCommunication.inLinkType = NO_COMM;
	//MEMCLR (&obCommunication, sizeof (COMM_OBJECT));
	//memset((void *)&obCommunication, 0x00, sizeof(COMM_OBJECT));
	//LIEM : do not ever clear obCommunication, app will crash 
	//while processing after check comm and before calling send comm.
	//maybe softpay use one of COMM_OBJECT data, if have time check inside SEND_AND_RECEIVE

	//because of this pitfall, becarefull to ensure that inDeinitialize be called only one time
	return 1;
}

int inImamExit(TRANSACTION_OBJECT *pobTran)
{
#ifdef __arm
	short shTaskNum = 0;
#endif
#ifdef  _TARG_68000
	int shTaskNum = 0;
#endif

	int inRet = 0;

	inRet = EESL_get_number_of_tasks(&shTaskNum);  //VMAC already run 2 tasks + 1 softpays if any + 1 catm if any
	LOG_PRINTFF((0x08L, "NUMBER OF TASK (%d) = [%d]", inRet, shTaskNum));

	if (inMAMAvailable && inRet==0 && shTaskNum>3) {
		LOG_PRINTFF((0x08L, "EXIT DETECTED"));
		clrscr();
		DisplayStatus("Releasing Comm...");
		inImamReleaseComm();
		LOG_PRINTFF((0x08L, "COMM RELEASED"));
		inDoDeActivate();
	}
	return (VS_SUCCESS);
}

int inImamExitByCancel(TRANSACTION_OBJECT *pobTran)
{
#ifdef __arm
	short shTaskNum = 0;
#endif
#ifdef  _TARG_68000
	int shTaskNum = 0;
#endif

	int inRet = 0;
	static unsigned long ticks = 0L;
	unsigned long CurrTicks;

	inRet = EESL_get_number_of_tasks(&shTaskNum);  //VMAC already run 2 tasks + 1 softpays if any + 1 catm if any
	LOG_PRINTFF((0x08L, "NUMBER OF TASK (%d) = [%d]", inRet, shTaskNum));

	if (inMAMAvailable && inRet==0 && shTaskNum>3) {
		CurrTicks = read_ticks();
		LOG_PRINTFF((0x08L, "Time Taken Between 2 Cancel = [%ld]", CurrTicks-ticks));
		if (CurrTicks-ticks>350) {
			ticks = CurrTicks;
		} else {
			LOG_PRINTFF((0x08L, "EXIT DETECTED"));
			clrscr();
			DisplayStatus("Releasing Comm...");
			inImamReleaseComm();
			LOG_PRINTFF((0x08L, "COMM RELEASED"));
			inDoDeActivate();
		}
	}
	return (VS_SUCCESS);
}

void vdImamCheckIdleTimeOut(void) 
{
	static unsigned long lnLocalModemTicks = 0L;
	unsigned long ticks = 0L;
    if (CHECK_TIMEOUT(srGDS.ulIdleTimerCount) == 0) {
        //if (srGDS.fHandHeld && srGDS.fBatteryOperated && get_dock_status() == HANDHELD_UNDOCKED) {  // : This only applicable for O3600
		if (get_dock_status() == HANDHELD_UNDOCKED) {  // : I decided not to modify srGDS.fHandHeld && srGDS.fBatteryOperated
		    //LOG_PRINTFF((0x08L, "TERMINAL PREPARE TO SLEEP/LOCK..."));
/*
		    if (inImamSetModemToSleep()==1){
				ticks = read_ticks();
				LOG_PRINTFF((0x08L, "TERMINAL IS SLEEPING..."));
				vdTerminalSleep();
				LOG_PRINTFF((0x08L, "SLEEP TIME = [%ld ms]", read_ticks()-ticks));
				fDisplayIdleMenu = VS_TRUE;
		    }
*/
			if (inImamUnlockKeyboard==1){
				if (lnBackLightTimer==0L){
				} else {
					vdImamUnlockKeyboardAndDisplayOn(0);
				}
			}
        } 
        // Reset Idle Timer
        srGDS.ulIdleTimerCount = set_itimeout(NO_CLOCK_HANDLE inGetIdleTimeOut(), TM_SECONDS);
		srGDS.ulIdleTimerCount = srGDS.ulIdleTimerCount + (lnBackLightTimer-120000L);  //
        if (shGetCurrentMenuID() != ROOT_MENU_INDEX)
            inCancelKeyResponder();
    } else {
		//LOG_PRINTFF((0x08L, "CURR_TICKS[%ld] --- IDLE[%ld]", read_ticks(), srGDS.ulIdleTimerCount));
	}

	if (inImamUnlockKeyboard==0){
		if (inImamModemLowPower==0){
			if ((lnModemTimer>0L) && (read_ticks()-lnLocalModemTicks >= lnModemTimer)){
				inImamModemLowPower = 1;
			}
		}
	} else {
		lnLocalModemTicks = read_ticks();
		inImamModemLowPower = 0;
	}
}

int inImamIdleLoop (TRANSACTION_OBJECT *pobTran)
{
	static unsigned long ticks = 0L;
	unsigned long curr_ticks = 0L;
	int inBatteryLevel = 0;
	int inBatteryStatus = 0;
	static int inChargingFactor = 0L;
	static int inEver = 0;
	int set_license_status = 0;


	disable_hot_key();
	if (inEver == 0) {
		inImamResetLogonStatus(pobTran);
		inImamLogonNow = 1;
		//inImamWaveSetPollMode(1);
		//inEver = 1;
	}
	if (inImamLogonNow == 1){
		enable_hot_key();

		// dota_license - force input license (if none / incorrect at dld) before logon.
		do{
			if (!inImamCheckLicense(pobTran)) {
				set_license_status = inImamSetLicense(pobTran);
			} else {
				set_license_status = 1;
			}
			if (set_license_status > 0) {
				if (!inImamCheckLicense(pobTran)) {
					DisplayStatus("License Key Mismatch.");
					vdWarnBeep();
					SVC_WAIT(2000);
					set_license_status = 0;
				}
			}
		} while (set_license_status <= 0);
		#if 0// imam set Logon To ECho may 7 2011
		inImamActionIDEventResponder(IMAMM_LOGON);
		#else
		
		#ifndef __arm
		inImamActionIDEventResponder(IMAMM_ECHO);
		#endif
		#endif		
		inImamLogonNow = 0;
	}
	//vdCheckIdleTimeOut();  //: Move from  inDisplayAtIdle
	vdImamCheckIdleTimeOut();  //: Move from  inDisplayAtIdle
	
	if (inEver == 0){
		vdImamDisplayMenu(0);
		inEver = 1;
	}
	curr_ticks = read_ticks();
	if (curr_ticks < ticks || curr_ticks>ticks + 1000L){
	} else {
		return VS_SUCCESS;
	}

	inBatteryStatus = get_battery_status();
	if (get_dock_status()==HANDHELD_UNDOCKED){
		inBatteryLevel = get_battery_charge();
		inImamDisplayBatteryLevel(inBatteryLevel);
	} else {
		inBatteryLevel = get_battery_charge();
		if ((inBatteryLevel>=0) && (inBatteryLevel<99)) {
			inBatteryLevel = inBatteryLevel + inChargingFactor;
			if (inBatteryLevel>=100) {
				if (inChargingFactor > 0) {
					inChargingFactor = 0;
					inImamDisplayBatteryLevel(inBatteryLevel);
				}
			} else {
				inChargingFactor += 10;
				inImamDisplayBatteryLevel(inBatteryLevel);
			}								
		}
		if (inImamUnlockKeyboard==0){
			vdImamUnlockKeyboardAndDisplayOn(1);
		}
	}
	ticks = curr_ticks;
	return VS_SUCCESS;
}

int inImamBatchCorrection(TRANSACTION_OBJECT *pobTran)
{
    int inCount;
	int inHostIndex;
    int inNoMITRecs = inGetMITTotRecs();
	int inTrxFound;
	int inTrxCount;

    for (inCount = 0; inCount < inNoMITRecs; inCount++) {
        if (inLoadMITRec(inCount) != VS_SUCCESS) return VS_SUCCESS;
	
		inTrxFound = 0;
		for (inHostIndex = 0; inHostIndex < MAX_HOSTS; ++inHostIndex) {
			if (inLoadHDTRec(inHostIndex) != VS_SUCCESS) return VS_SUCCESS;
			inTrxCount = inGetHostTranCnt(pobTran);
			if ( inTrxCount > 0 ) {
				LOG_PRINTFF((0x08L, "[%d, %d]THERE IS TRX = COUNT[%d]", inCount, inHostIndex, inTrxCount));
				inTrxFound = inTrxFound + inTrxCount;
				break;
			}
		}
		if (inTrxFound == 0){
			vdCloseDCBatch(pobTran);
			vdBatchDCOpen(pobTran);
			if (pobTran->dbBatch.kfile.num_of_recs > 0L) {
				LOG_PRINTFF((0x08L, "BATCH NOT EMPTY = REC-COUNT[%d]", (int)pobTran->dbBatch.kfile.num_of_recs));
				if (inClrBatch(pobTran, CLEAR_BATCH, VS_FALSE) == VS_SUCCESS) {inCPACIncBatchNum();}
			} else {
				LOG_PRINTFF((0x08L, "BATCH EMPTY"));
			}
			vdCloseDCBatch(pobTran);
/*
			vdCloseTabBatch(pobTran);
			vdBatchOTOpen(pobTran);
			if (pobTran->dbOTBatch.kfile.num_of_recs > 0L) {
				LOG_PRINTFF((0x08L, "TAB NOT EMPTY = REC-COUNT[%d]", (int)pobTran->dbOTBatch.kfile.num_of_recs));
				if (inDeleteOpenTabBatch(pobTran) != VS_SUCCESS) {continue;}
			} else {
				LOG_PRINTFF((0x08L, "TAB EMPTY"));
			}
			vdCloseTabBatch(pobTran);
*/
		}
    }
	return VS_SUCCESS;
}
/*
VS_BOOL fchkrevfile(TRANSACTION_OBJECT* pobTran) {
    int inHostIndex;
    char stRevFileName[FILENAME_SIZE + 1];

    for (inHostIndex = 0; inHostIndex < MAX_HOSTS; ++inHostIndex) {
        vdGetReversalFileName(stRevFileName, inHostIndex);
        strcat(stRevFileName, ROC_FILE_EXTN);
        if (inChkFileExist(stRevFileName) == VS_SUCCESS)
            return(VS_FALSE);

        vdGetReversalFileName(stRevFileName, inHostIndex);
        strcat(stRevFileName, OFFLINE_FILE_EXTN);
        if (inChkFileExist(stRevFileName) == VS_SUCCESS)
            return(VS_FALSE);

        vdGetReversalFileName(stRevFileName, inHostIndex);
        strcat(stRevFileName, REVERSAL_FILE_EXTN);
        if (inChkFileExist(stRevFileName) == VS_SUCCESS)
            return(VS_FALSE);
    }
    return(VS_TRUE);
}

VS_BOOL fReversalsEmpty() {
    char stRevFileName[FILENAME_SIZE + 1];
    int inNoMITRecs = inGetMITTotRecs();
    int inCount;
    int inHostIndex;

    for (inCount = 0; inCount < inNoMITRecs; inCount++) {
        inLoadMITRec(inCount);

        for (inHostIndex = 0; inHostIndex < MAX_HOSTS; ++inHostIndex) {
            vdGetReversalFileName(stRevFileName, inHostIndex);
            strcat(stRevFileName, ROC_FILE_EXTN);
            if (inChkFileExist(stRevFileName) == VS_SUCCESS)
                return(VS_FALSE);

            vdGetReversalFileName(stRevFileName, inHostIndex);
            strcat(stRevFileName, OFFLINE_FILE_EXTN);
            if (inChkFileExist(stRevFileName) == VS_SUCCESS)
                return(VS_FALSE);

            vdGetReversalFileName(stRevFileName, inHostIndex);
            strcat(stRevFileName, REVERSAL_FILE_EXTN);
            if (inChkFileExist(stRevFileName) == VS_SUCCESS)
                return(VS_FALSE);
        }
    }
    return(VS_TRUE);
}

    vdGetReversalFileName(szRevFileName, inHostIndex);
    strcat(szRevFileName, BACKUP_REV_FILE_EXTN);
    if (inChkFileExist(szRevFileName) == VS_SUCCESS)
        remove(szRevFileName);

*/

int inImamWirelessConnect (TRANSACTION_OBJECT *pobTran)
{
	int inRetVal = VS_SUCCESS;
#ifdef IMAM_UCL
	inHostConnectionTest();
#endif
	return inRetVal;
}

int inImamSelectComm (TRANSACTION_OBJECT *pobTran)
{
//#define	ASPEN_MODEM_ID		2
//#define	TDK_MODEM_ID		3
//#define	CONNEXANT_MODEM_ID	4
//#define   OMNI_3750_ID	"Q5"
//#define OMNI_3300_ID	"Q7"
//#define OMNI_3350_ID	"Q3"
//#define OMNI_3600_ID	"Q8"
//#define OMNI_3750_ID	"Q5"
//#define OMNI_5150_ID    "QA"

/* Values returned by SVC_INFO_MOD_ID and SVC_INFO_MODULE_ID */
//#define MID_TDK_ONLY            (3)     // TDK 2.4 modem only
//#define MID_CARLOS_ONLY         (5)     // Carlos (Aspen144) modem only
//#define MID_CO561_ONLY          (6)     // Connect One 10BaseT only
//#define MID_CARLOS_CO561        (7)     // Carlos/CO 10baseT combo
//#define MID_CARLOS_MC56         (12)    // Carlos/GSM US combo
//#define MID_CARLOS_MC55         (13)    // Carlos/GSM Int combo
//#define MID_CARLOS_EM3420       (14)    // Carlos/CDMA combo
//#define MID_CARLOS_CO710        (15)    // Carlos/WiFi combo

	int inRetVal = 0;
	int inModemType = 0;
	int inPortModem = 0;
	int inModuleID = 0;
	int inSecondModuleID = 0;
	int inCurrComm = 0;
	char buff[128];
   
	inLoadPCLRec(0);
	inCurrComm = inGetImamUCLComm();
	
	memset(buff, 0x00, sizeof(buff));
	SVC_INFO_EPROM(buff);
	inModemType = SVC_INFO_MOD_ID();
	inPortModem = SVC_INFO_PORT_MODEM();
	inModuleID  = SVC_INFO_MODULE_ID (inPortModem);
	inSecondModuleID = SVC_INFO_MODULE_ID(2);
    
	LOG_PRINTFF((0x08L, "Current UCL.COMM = [%d]", inCurrComm));
	LOG_PRINTFF((0x08L, "EPROM = [%s]", buff));
	LOG_PRINTFF((0x08L, "Modem Type = [%d]", inModemType));
	LOG_PRINTFF((0x08L, "Modem Port = [%d]", inPortModem));
	LOG_PRINTFF((0x08L, "Module ID of Port[%d] = [%d]", inPortModem, inModuleID));
	LOG_PRINTFF((0x08L, "Module ID of Port[2] = [%d]", inSecondModuleID));

	if (strstr(buff, "Q5") != (char *) NULL) { //OMNI_3750_ID=="Q5"
		inRetVal = obDisp.inDO_ChooseOne( NULL, "Select Comm?", "Dial-Up~Ethernet~CDMA", 3, NULL_PFI );
		LOG_PRINTFF((0x08L, "Select = [%d]", inRetVal));
		if (inRetVal<1 || inRetVal>3) return (VS_SUCCESS);
		if ((inModuleID==3 && inRetVal==2) || 
			(inModuleID==3 && inRetVal==3) ||
			(inModuleID==5 && inRetVal==2) || 
			(inModuleID==5 && inRetVal==3) || 
			(inModuleID==6 && inRetVal==1) || 
			(inModuleID==6 && inRetVal==3) ||
			(inModuleID==7 && inRetVal==3) ||
			(inModuleID==14 && inRetVal==2)){
			DisplayStatus("NOT AVAILABLE!");
			SVC_WAIT(2000);
			return (VS_SUCCESS);
		}
		if (inModuleID!=3 && inModuleID!=5 && inModuleID!=6 && inModuleID!=7 && inModuleID!=14) {
			DisplayStatus("UNSUPPORTED MODEM!");
			SVC_WAIT(2000);
			return (VS_SUCCESS);
		}
		if ((inCurrComm==0 && inRetVal==1) ||
			(inCurrComm==4 && inRetVal==2) ||
			(inCurrComm==7 && inRetVal==3)) {
			DisplayStatus("COMM IN USE!");
			SVC_WAIT(2000);
			return (VS_SUCCESS);
		}
		DisplayStatus("Release comm...");
		inImamReleaseComm();
		if (inRetVal==1) {
			vdSetImamUCLComm(0);
		} else if (inRetVal==2) {
			vdSetImamUCLComm(4);
		} else if (inRetVal==3) {
			vdSetImamUCLComm(7);
		}
		SVC_WAIT(2000);
		DisplayStatus("Init new comm...");
		inUpdatePCLRec();
		inImamInitUclCommEx();
		return (VS_SUCCESS);
	} else if (strstr(buff, "QA") != (char *) NULL) { //#define OMNI_5150_ID  "QA"
		inRetVal = obDisp.inDO_ChooseOne( NULL, "Select Comm?", "Dial-Up~Ethernet", 2, NULL_PFI );
		LOG_PRINTFF((0x08L, "Select = [%d] IMAM", inRetVal));
		if (inRetVal<1 || inRetVal>2) return (VS_SUCCESS);
		if (inRetVal == 2)
			{ 
					 inImamReleaseComm();
				{	LOG_PRINTFF((0x08L, "Select  ETERNET IMAM= [%d]", inRetVal));
					vdSetImamUCLComm(4);
				} 
				SVC_WAIT(2000);
				DisplayStatus("Init new comm...");
				inUpdatePCLRec();
				inImamInitUclCommEx();
				return (VS_SUCCESS);

			}
			
		if (inRetVal != 1) {
			DisplayStatus("NOT AVAILABLE!");
			SVC_WAIT(2000);
			return (VS_SUCCESS);
		}
		else if ((inCurrComm==0 && inRetVal==1) ||
			(inCurrComm==4 && inRetVal==2)) {
			DisplayStatus("COMM IN USE!");
			SVC_WAIT(2000);
			return (VS_SUCCESS);
		}
		DisplayStatus("Release comm...");
		inImamReleaseComm();
		if (inRetVal==1) {
			vdSetImamUCLComm(0);
		} else if (inRetVal==2) {	LOG_PRINTFF((0x08L, "Select  ETERNET IMAM= [%d]", inRetVal));
			vdSetImamUCLComm(4);
		} 
		SVC_WAIT(2000);
		DisplayStatus("Init new comm...");
		inUpdatePCLRec();
		inImamInitUclCommEx();
		return (VS_SUCCESS);
	}
	else if (strstr(buff, "QG") != (char *) NULL) { //#define OMNI_5150_ID  "QA"
		inRetVal = obDisp.inDO_ChooseOne( NULL, "Select Comm?", "Dial-Up~Ethernet", 2, NULL_PFI );
		LOG_PRINTFF((0x08L, "Select = [%d] IMAM", inRetVal));
		if (inRetVal<1 || inRetVal>2) return (VS_SUCCESS);
		if (inRetVal == 2)
			{ 
					 inImamReleaseComm();
				{	LOG_PRINTFF((0x08L, "Select  ETERNET IMAM= [%d]", inRetVal));
					vdSetImamUCLComm(4);
				} 
				SVC_WAIT(2000);
				DisplayStatus("Init new comm...");
				inUpdatePCLRec();
				inImamInitUclCommEx();
				return (VS_SUCCESS);

			}
			
		if (inRetVal != 1) {
			DisplayStatus("NOT AVAILABLE!");
			SVC_WAIT(2000);
			return (VS_SUCCESS);
		}
		else if ((inCurrComm==0 && inRetVal==1) ||
			(inCurrComm==4 && inRetVal==2)) {
			DisplayStatus("COMM IN USE!");
			SVC_WAIT(2000);
			return (VS_SUCCESS);
		}
		DisplayStatus("Release comm...");
		inImamReleaseComm();
		if (inRetVal==1) {
			vdSetImamUCLComm(0);
		} else if (inRetVal==2) {	LOG_PRINTFF((0x08L, "Select  ETERNET IMAM= [%d]", inRetVal));
			vdSetImamUCLComm(4);
		} 
		SVC_WAIT(2000);
		DisplayStatus("Init new comm...");
		inUpdatePCLRec();
		inImamInitUclCommEx();
		return (VS_SUCCESS);
	}
	else if (strstr(buff, "QB") != (char *) NULL) { //Vx610 == "QB"
		inRetVal = obDisp.inDO_ChooseOne( NULL, "Select Comm?", "Dial~WiFi~GPRS~CDMA", 4, NULL_PFI );
		LOG_PRINTFF((0x08L, "Select = [%d]", inRetVal));
		if (inRetVal<1 || inRetVal>4) return (VS_SUCCESS);

		if (inModuleID==4 && inRetVal==1) {
		} else if (inSecondModuleID==255 && inRetVal==4) { //255==CDMA?
		} else if (inSecondModuleID==9   && inRetVal==3) { //9  ==GPRS
		} else {
			DisplayStatus("NOT AVAILABLE!");
			SVC_WAIT(2000);
			return (1);
		}
		if ((inCurrComm==0 && inRetVal==1) ||
			(inCurrComm==5 && inRetVal==2) ||
			(inCurrComm==6 && inRetVal==3) ||
			(inCurrComm==7 && inRetVal==4) ) {
			DisplayStatus("COMM IN USE!");
			SVC_WAIT(2000);
			return (VS_SUCCESS);
		}
		DisplayStatus("Release comm...");
		inImamReleaseComm();
		if (inRetVal==1) {
			vdSetImamUCLComm(0);
		} else if (inRetVal==2) {
			vdSetImamUCLComm(5);
		} else if (inRetVal==3) {
			vdSetImamUCLComm(6);
		} else if (inRetVal==4) {
			vdSetImamUCLComm(7);
		} 
		SVC_WAIT(2000);
		DisplayStatus("Init new comm...");
		inUpdatePCLRec();
		inImamInitUclCommEx();
		return (VS_SUCCESS);
	} else {
		DisplayStatus("UNSUPPORTED TERMINAL!");
		SVC_WAIT(2000);
		return (VS_SUCCESS);
	}
}

int inImamSetMasterKey (TRANSACTION_OBJECT *pobTran)
{
    int inResult=1;
	char buff[128];
	char MKAddress;
	int i;
/*
	do {
		memset(buff, 0x00, sizeof(buff));
		vdDisplayAt(1, 7, " ", CLR_EOL);
		vdDisplayAt(1, 8, " ", CLR_EOL);
		if (inResult>=0) inResult = InputString("MK Addr [0-5]: ", buff);
		if (inResult<0) return (VS_ESCAPE);
		for (i=0; i<strlen(buff); i++) {
			if ((buff[i]<'0') || (buff[i]>'5')){
				DisplayStatus("Invalid Input");
				SVC_WAIT(1000);
				memset(buff, 0x00, sizeof(buff));
				break;
			}
		}
	} while (strlen(buff)!=1);
*/
	memset(buff, 0x00, sizeof(buff));
	sprintf(buff, "%d", inGetHostHandle());
	MKAddress = buff[0];
	vdDisplayAt(1, inImamLineNumber-1, " ", CLR_EOL);
	vdDisplayAt(1, inImamLineNumber, " ", CLR_EOL);
	sprintf(buff, "MK Addr: [%c]", MKAddress);
	vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
	
	vdScrollDisplay();
	vdScrollDisplay();
	do {
		memset(buff, 0x00, sizeof(buff));
		vdDisplayAt(1, inImamLineNumber-1, " ", CLR_EOL);
		vdDisplayAt(1, inImamLineNumber, " ", CLR_EOL);
		if (inResult>=0) inResult = InputString("KEY: ", buff);
		if (inResult<0) return (VS_ESCAPE);
		for (i=0; i<strlen(buff); i++) {
			if ((buff[i]<'0') || ((buff[i]>'9')&&(buff[i]<'A')) || (buff[i]>'F')){
				DisplayStatus("Invalid Input");
				SVC_WAIT(1000);
				memset(buff, 0x00, sizeof(buff));
				break;
			}
		}
	} while (strlen(buff)!=16);
#ifdef IMAM_PERMATA
	if (inResult>=0) inResult = inImamTransferMasterKey('0', buff);
	SVC_WAIT(500);
	if (inResult>=0) inResult = inImamTransferMasterKey('1', buff);
	SVC_WAIT(500);
	if (inResult>=0) inResult = inImamTransferMasterKey('2', buff);
	SVC_WAIT(500);
	if (inResult>=0) inResult = inImamTransferMasterKey('3', buff);
#else
  #ifdef IMAM_BNI
    inResult=  inImamSetMKey3D(pobTran);
   #else
	if (inResult>=0) inResult = inImamTransferMasterKey(MKAddress, buff);
    #endif	
#endif
	if (inResult==VS_SUCCESS) {
		DisplayStatus("MasterKey Injected");
	} else {
		DisplayStatus("Fail, Try Again");
		vdWarnBeep();
	}
	SVC_WAIT(3000);
	return (VS_SUCCESS);
}

int inImamDisplaySignalStrength (TRANSACTION_OBJECT *pobTran)
{
	int inRetVal = VS_SUCCESS;
#ifdef IMAM_UCL
	//inUpdateWirelessStatus();
#endif
	return inRetVal;
}


int inImamLoadGetCDTIndex (TRANSACTION_OBJECT *pobTran, char *pchPan)
{
	int inResult, inRetVal, inRecIndex;
	int inNumberOfMatches;
	int inRecNumArray[ 4 ] ;
	int inCardTypeArray [] = {-1, -1, -1, -1};
	int inHostTypeArray [] = {-1, -1, -1, -1};
	int inIssuerTypeArray [] = {-1, -1, -1, -1};
	char szChoiceMsg[ MESSAGE_SIZE + 1 + 64 ];
	int inIssuer, inImamHostIndex, inImamCardType;
	//long lnMsgNum;

	LOG_PRINTFF((0x08L, "--inImamLoadGetCDTIndex--"));

    vdSGCurCDTIndex(-1);
	inRetVal = VS_ERR;
	inRecIndex = 0;

    inNumberOfMatches = 0;
    inIssuer = 0;
	inImamHostIndex = -99;
	inImamCardType = -99;
    memset( szChoiceMsg, 0x00, sizeof( szChoiceMsg ));

    if (strlen(pchPan)<=0)
       return(VS_ERR);

	do {
		inResult = inLoadCDTRec( inRecIndex );
		if( inResult == VS_ERR ) 
			break;
		
		{ //LOAD HDT to check if the card is belong to GUEST HOST
			inLoadHDTRec(inGetHostIndex());
			if (fGetImamGuestHost()){
				inRecIndex++;
				continue;
			}
		}
		
		if ((strncmp(pchPan, szGetPANLo(), min(strlen(pchPan), strlen(szGetPANLo()))) >= 0)
		 && (strncmp(pchPan, szGetPANHi(), min(strlen(pchPan), strlen(szGetPANHi()))) <= 0)) {
		    if (pobTran->fInteracDebit) {
    			inRetVal = inRecIndex;
	    		break;
		    }
			//: Debit card will be into account if debitflag is ON
			//: Manual Entry is only allowed if ManualEntry in CDT is ON
			if ( !(fGetDebitFlag() == VS_FALSE && inGetType() == DEBIT_CARD) &&
			     !(!fGetManEntry() && pobTran->srBRec.fManual == VS_TRUE)) {
			    if ((inGetType() != inImamCardType))  {
					{  //Improving card type selection
						int i;
						int found = 0;
						for (i=0; i<inNumberOfMatches; i++) {
							if (inGetType() == inCardTypeArray[i]) {
								inRecIndex++;
								found = 1;
								break;
							}
						}
						if (found) continue;
						inCardTypeArray[inNumberOfMatches] = inGetType();
					}
					inImamCardType = inGetType();
					inRecNumArray[ inNumberOfMatches++ ] = inRecIndex;
					if(inNumberOfMatches > 1)
			    		szChoiceMsg[ strlen( szChoiceMsg )] = '~';

					if (inImamCardType == ADMIN_CARD) {
						strcat(szChoiceMsg, "Admin");
					} else if (inImamCardType == CREDIT_CARD) {
						strcat(szChoiceMsg, "CREDIT");  //==CREDIT & DEBIT NON-PIN
					} else if (inImamCardType == DEBIT_CARD) {
						strcat(szChoiceMsg, "DEBIT/PIN");
					} else if (inImamCardType == NON_CARD) {
						strcat(szChoiceMsg, "Non-Card");
					} else if (inImamCardType == LOYALTY_CARD) {
						strcat(szChoiceMsg, "Loyalty");
					} else if (inImamCardType == LOYCREDIT_CARD) {
						strcat(szChoiceMsg, "Loyalty+Credit");
					} else if (inImamCardType == EBT_CARD) {
						strcat(szChoiceMsg, "EBT");
					} else if (inImamCardType == PURCHASE_CARD) {
						strcat(szChoiceMsg, "Purchase");
					} else if (inImamCardType == COMMERCIAL_CARD) {
						strcat(szChoiceMsg, "Commercial");
					} else if (inImamCardType == FLEET_CARD) {
						strcat(szChoiceMsg, "Fleet");
					} else {
						strcat(szChoiceMsg, "????");
					}

					if( inNumberOfMatches > 3 )
        				break;
    		    }
    		}
    	}
		inRecIndex++;

	} while (1);

    if( inNumberOfMatches == 1 ) {
        inRetVal = inRecNumArray[0];
    } else if( inNumberOfMatches > 1 ) {
		vdClearASCII8x21Window(1, 3, 21, 8);
		inRetVal = obDisp.inDO_ChooseOne( NULL, "CARD TYPE?", szChoiceMsg, inNumberOfMatches, NULL_PFI );
        if (inRetVal==VS_ESCAPE) {
            return(VS_ESCAPE);
        }
        inRetVal = inRecNumArray[inRetVal - 1];
    }
	if (inRetVal < 0) {
		vdResetCDTRec();
		return inRetVal;
	} else if( inRetVal >= 0 ) {
    	inLoadCDTRec( inRetVal );
		vdSGCurCDTIndex(inRetVal);  /* Remember the current CDT that is loaded */
   	    inGetIssuerRecord(inGetIssuerNum());
		inImamCardType = inGetType();
		pobTran->srBRec.inTranCardType = inGetType();  // need to add because we add new type card CUP_CARD
    }

/////////////////////////////////////////////////
/////////////////////////////////////////////////
    vdSGCurCDTIndex(-1);
	inRetVal = VS_ERR;
	inRecIndex = 0;
    inNumberOfMatches = 0;
    inIssuer = 0;
	inImamHostIndex = -99;
    memset( szChoiceMsg, 0x00, sizeof( szChoiceMsg ));
	do
	{
		inResult = inLoadCDTRec( inRecIndex );
		if( inResult == VS_ERR )
			break;

		{ //LOAD HDT to check if the card is belong to GUEST HOST
			inLoadHDTRec(inGetHostIndex());
			if (fGetImamGuestHost()){
				inRecIndex++;
				continue;
			}
		}
		if ((strncmp(pchPan, szGetPANLo(), min(strlen(pchPan), strlen(szGetPANLo()))) >= 0)
		 && (strncmp(pchPan, szGetPANHi(), min(strlen(pchPan), strlen(szGetPANHi()))) <= 0)) {
		    if (pobTran->fInteracDebit) {
    			inRetVal = inRecIndex;
	    		break;
		    }
			if ( !(fGetDebitFlag() == VS_FALSE && inGetType() == DEBIT_CARD) &&
			     !(!fGetManEntry() && pobTran->srBRec.fManual == VS_TRUE)) {
			    if ((inGetType() == inImamCardType ) && (inGetIssuerNum() != inIssuer )){
					if (inGetIssuerRecord(inGetIssuerNum()) == VS_SUCCESS) {
						{  //Improving card type selection
							int i;
							int found = 0;
							for (i=0; i<inNumberOfMatches; i++) {
								if (inGetIssuerNum() == inIssuerTypeArray[i]) {
									inRecIndex++;
									found = 1;
									break;
								}
							}
							if (found) continue;
							inIssuerTypeArray[inNumberOfMatches] = inGetIssuerNum();
						}
						inIssuer = inGetIssuerNum();
						inRecNumArray[ inNumberOfMatches++ ] = inRecIndex;
						if(inNumberOfMatches > 1)
			    			szChoiceMsg[ strlen( szChoiceMsg )] = '~';

						strcat(szChoiceMsg, szGetIssuerLabel());
					}
					if( inNumberOfMatches > 3 )
        				break;
    		    }
    		}
    	}
		inRecIndex++;
	} while (1);

    if( inNumberOfMatches == 1 ) {
        inRetVal = inRecNumArray[0];
	} else if( inNumberOfMatches > 1 ) {
		vdClearASCII8x21Window(1, 3, 21, 8);
		inRetVal = obDisp.inDO_ChooseOne( NULL, "ISSUER?", szChoiceMsg, inNumberOfMatches, NULL_PFI );
        if (inRetVal==VS_ESCAPE) {
            return(VS_ESCAPE);
        }
        inRetVal = inRecNumArray[ inRetVal - 1];
    }
	if (inRetVal < 0) {
		vdResetCDTRec();
		return inRetVal;
	} else if( inRetVal >= 0 ) {
    	inLoadCDTRec( inRetVal );
		vdSGCurCDTIndex(inRetVal);  /* Remember the current CDT that is loaded */
   	    inGetIssuerRecord(inGetIssuerNum());
		inIssuer = inGetIssuerNum();
    }

////////////////////////////////////////////////////////
///////////////////////////////////////////////////
    vdSGCurCDTIndex(-1);
	inRetVal = VS_ERR;
	inRecIndex = 0;
    inNumberOfMatches = 0;
	inImamHostIndex = -99;
    memset( szChoiceMsg, 0x00, sizeof( szChoiceMsg ));
	do
	{
		inResult = inLoadCDTRec( inRecIndex );
		if( inResult == VS_ERR )
			break;

		{ //LOAD HDT to check if the card is belong to GUEST HOST
			inLoadHDTRec(inGetHostIndex());
			if (fGetImamGuestHost()){
				inRecIndex++;
				continue;
			}
		}
		if ((strncmp(pchPan, szGetPANLo(), min(strlen(pchPan), strlen(szGetPANLo()))) >= 0)
		 && (strncmp(pchPan, szGetPANHi(), min(strlen(pchPan), strlen(szGetPANHi()))) <= 0)) {
		    if (pobTran->fInteracDebit) {
    			inRetVal = inRecIndex;
	    		break;
		    }
			if ( !(fGetDebitFlag() == VS_FALSE && inGetType() == DEBIT_CARD) &&
			     !(!fGetManEntry() && pobTran->srBRec.fManual == VS_TRUE)) {
			    if ((inGetType() == inImamCardType) && (inGetIssuerNum() == inIssuer) && (inGetHostIndex() != inImamHostIndex)) {					
					if (inLoadHDTRec(inGetHostIndex()) == VS_SUCCESS) {
						{  //Improving card type selection
							int i;
							int found = 0;
							for (i=0; i<inNumberOfMatches; i++) {
								if (inGetHostIndex() == inHostTypeArray[i]) {
									inRecIndex++;
									found = 1;
									break;
								}
							}
							if (found) continue;
							inHostTypeArray[inNumberOfMatches] = inGetHostIndex();
						}
						inImamHostIndex = inGetHostIndex();
						inRecNumArray[ inNumberOfMatches++ ] = inRecIndex;
						if(inNumberOfMatches > 1)
			    			szChoiceMsg[ strlen( szChoiceMsg )] = '~';

						strcat(szChoiceMsg, szGetHostName());
					}
					if( inNumberOfMatches > 3 )
        				break;
    		    }
    		}
    	}
		inRecIndex++;
	} while (1);

    if( inNumberOfMatches == 1 ) {
        inRetVal = inRecNumArray[0];
	} else if( inNumberOfMatches > 1 ) {
		vdClearASCII8x21Window(1, 3, 21, 8);
		inRetVal = obDisp.inDO_ChooseOne( NULL, "MERC HOST?", szChoiceMsg, inNumberOfMatches, NULL_PFI );
        if (inRetVal==VS_ESCAPE){
            return(VS_ESCAPE);
        }
        inRetVal = inRecNumArray[ inRetVal - 1];
    }
////////////////////////////////////////////////
////////////////////////////////////////////////
//At the end, we load a CDT as below
	/* return value is important, not != VS_SUCCESS */
	if (inRetVal < 0) {
		vdResetCDTRec();
		return inRetVal;
	} else if( inRetVal >= 0 ) {
    	inLoadCDTRec( inRetVal );
		vdSGCurCDTIndex(inRetVal);  /* Remember the current CDT that is loaded */
    	/* Get the CDT also for card labels */
   	    inGetIssuerRecord(inGetIssuerNum());
		if (fGetImamSelectAcc()) {//Select Account
			SVC_WAIT(3000);
			vdClearASCII8x21Window(1, 3, 21, 8);
			if (fGetImamPrivateLabel()) {  //LIPPO
				strcpy((char *)szChoiceMsg, "SAVING~CURRENT");
				inRetVal = obDisp.inDO_ChooseOne( NULL, "SELECT ACC?", szChoiceMsg, 2, NULL_PFI );
				pobTran->srBRec.chECI = inRetVal * 16;  //so chECI = 0x10 ... 0x20
#ifdef IMAM_PERMATA
			} else if (inGetType() == DEBIT_CARD){
				strcpy((char *)szChoiceMsg, "SAVING~CURRENT");
				inRetVal = obDisp.inDO_ChooseOne( NULL, "SELECT ACC?", szChoiceMsg, 2, NULL_PFI );
				pobTran->srBRec.chECI = inRetVal * 16;  //so chECI = 0x10 ... 0x20
#endif
//edi - choice saving current
#ifdef IMAM_DANAMON
			} else if (inGetType() == DEBIT_CARD){
				strcpy((char *)szChoiceMsg, "SAVING~CURRENT");
				inRetVal = obDisp.inDO_ChooseOne( NULL, "SELECT ACC?", szChoiceMsg, 2, NULL_PFI );
				pobTran->srBRec.chECI = inRetVal * 16;  //so chECI = 0x10 ... 0x20
#endif
			}else { //INDOPAY - ARTAJASA
				strcpy((char *)szChoiceMsg, "DEFAULT~SAVING~CURRENT~CREDIT");
				inRetVal = obDisp.inDO_ChooseOne( NULL, "SELECT ACC?", szChoiceMsg, 4, NULL_PFI );
				pobTran->srBRec.chECI = (inRetVal - 1) * 16;  //so chECI = 0x00 ... 0x30
			}
			if (inRetVal==VS_ESCAPE){
				return(VS_ESCAPE);
			}
		}
    }
	LOG_PRINTFF((0x08L, "--inImamLoadGetCDTIndex--END"));
	return(inRetVal);
}

int inImamPrintISOPacket(VS_BOOL fSendPacket, unsigned char *pucMessage, int inLen) 
{
    extern PRINTER_OBJECT obPrinter;
    char ucLineBuffer[24 + 1 + 1];
    unsigned char *pucBuff;
    int inBuffPtr = 0;
    
	if (inEnablePrintISOTrace()==0)
		return (VS_SUCCESS);

      if (inLen <= 0)
          return(VS_SUCCESS);
      p350ColumnMode(COLUMN_TYPE_24);
      if (fSendPacket)
      {
          shSpool(&obPrinter, "Send ISO Packet\n");
      }
      else
      {
          shSpool(&obPrinter, "Receive ISO Packet\n");
      }
      
      shSpool(&obPrinter, "----\n");
      pucBuff = pucMessage + inLen;
      while (pucBuff > pucMessage)
      {
          MEMCLR(ucLineBuffer, sizeof(ucLineBuffer));
          for (inBuffPtr = 0; (inBuffPtr < 24) && (pucBuff > pucMessage); inBuffPtr += 3)
          {
               
              sprintf(&ucLineBuffer[inBuffPtr], "%02X ", *pucMessage);
              pucMessage++;
          }
          ucLineBuffer[24] = '\n';
          shSpool(&obPrinter, ucLineBuffer);
      }
      shSpool(&obPrinter, "\n----\n");
	  p350ColumnMode(COLUMN_TYPE_42);
      return (VS_SUCCESS);
}





int inImamCardTrxCheck(TRANSACTION_OBJECT *pobTran)
{

//pobTran->srBRec.inTranCardType != DEBIT_CARD
//pobTran->inChipStatus != EMV_CARD
//if (lnGGErrorMessage() == 0) vdSGErrorMessage (PREDIAL_ERROR_MSG21);
//#define inGGCode() pobTran->srBRec.inCode
//pobTran->srBRec.inChipStatus == EMV_CARD, This is very important value check

	if ((pobTran->srTRTRec.TransactionCode == SALE) && (!fGetCDTSale())) {
		vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
        return(VS_ERR);
	}
	if ((pobTran->srTRTRec.TransactionCode == IMAM_CARDVER) && (!fGetCDTCardVer())) {
		vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
        return(VS_ERR);
	}
	if ((pobTran->srTRTRec.TransactionCode == AUTH_ONLY) && (!fGetCDTAuthOnly())) {
		vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
        return(VS_ERR);
	}
	if ((pobTran->srTRTRec.TransactionCode == PRE_AUTH) && (!fGetCDTNormPreAuth())) {
		vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
        return(VS_ERR);
	}
	if ((pobTran->srTRTRec.TransactionCode == SALE_OFFLINE) && (!fGetCDTOffline())) {
		vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
        return(VS_ERR);
	}
	if ((pobTran->srTRTRec.TransactionCode == REFUND) && (!fGetCDTRefund())) {
		vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
        return(VS_ERR);
	}
	if ((pobTran->srTRTRec.TransactionCode == TIP_ADJUST) && (!fGetCDTTipAdjust())) {
		vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
        return(VS_ERR);
	}

	if ((pobTran->srTRTRec.TransactionCode == IMAM_PREAUTH || pobTran->srTRTRec.TransactionCode == IMAM_PREAUTH_CANCEL) && (!fGetCDTPreAuth())) {
		vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
        return(VS_ERR);
	}

	if ((pobTran->srTRTRec.TransactionCode == IMAM_PRECOMP || pobTran->srTRTRec.TransactionCode == IMAM_PRECOMP_CANCEL) && (!fGetCDTPreComp())) {
		vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
        return(VS_ERR);
	}

	if ((pobTran->srTRTRec.TransactionCode == DEBIT_BAL_INQ) && (inGetType() != DEBIT_CARD)) {
		vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
        return(VS_ERR);
	}

	if ((pobTran->srTRTRec.TransactionCode == POINT_BAL_INQ) && (inGetPaymentIndex()!=1)) {
		vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
        return(VS_ERR);
	}

/*
	if (inGetType()==DEBIT_CARD) {
		if (pobTran->srTRTRec.TransactionCode!=SALE && pobTran->srTRTRec.TransactionCode!=DEBIT_BAL_INQ) {
			vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
			return(VS_ERR);
		}
	}
*/
	if (fGetImamAirlineTrx()) {
		if ((pobTran->srTRTRec.TransactionCode == AUTH_ONLY) ||
			(pobTran->srTRTRec.TransactionCode == IMAM_CARDVER) ||
			(pobTran->srTRTRec.TransactionCode == PRE_AUTH) ||
			(pobTran->srTRTRec.TransactionCode == REFUND) ||
			(pobTran->srTRTRec.TransactionCode == TIP_ADJUST)) {
			vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
			return(VS_ERR);
		}
	}

	if (fGetImamPrivateLabel()) {
		if ((pobTran->srTRTRec.TransactionCode == AUTH_ONLY) ||
			(pobTran->srTRTRec.TransactionCode == IMAM_CARDVER) ||
			(pobTran->srTRTRec.TransactionCode == PRE_AUTH) ||
			(pobTran->srTRTRec.TransactionCode == REFUND) ||
			(pobTran->srTRTRec.TransactionCode == TIP_ADJUST)) {
			vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
			return(VS_ERR);
		}
	}

	if (pobTran->srBRec.inPlan >= 4) {
		if ((pobTran->srTRTRec.TransactionCode == AUTH_ONLY) ||
			(pobTran->srTRTRec.TransactionCode == IMAM_CARDVER) ||
			(pobTran->srTRTRec.TransactionCode == PRE_AUTH) ||
			(pobTran->srTRTRec.TransactionCode == REFUND) ||
			(pobTran->srTRTRec.TransactionCode == TIP_ADJUST)) {
			vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
			return(VS_ERR);
		}
	}

	if (((pobTran->srBRec.inChipStatus == EMV_CARD) || (pobTran->srBRec.inChipStatus == EMV_EASY_ENTRY_CARD))&&
		(!fGetImamEmvHost())
	){
		vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
		return(VS_ERR);
	}
    return (VS_SUCCESS);
}

int inBGMenuChoice(char *Label, char *MenuItem1, char *MenuItem2, char *MenuItem3, char *MenuItem4, int inBackGround)
{
	int i, karakter=0;
	int inMaxStrLen = 0;
	int ret=0,ret2=0;
	vdFlushKeyboardBuffer();
	vdClearNonTitleLines();

	if (strlen(MenuItem1)>15)	MenuItem1[15] = 0x00;
	if (strlen(MenuItem2)>15)	MenuItem2[15] = 0x00;
	if (strlen(MenuItem3)>15)	MenuItem3[15] = 0x00;
	if (strlen(MenuItem4)>15)	MenuItem4[15] = 0x00;
	if (strlen(Label)>15) Label[15] = 0x00;
	if (strlen(MenuItem1)>inMaxStrLen) inMaxStrLen = strlen(MenuItem1);
	if (strlen(MenuItem2)>inMaxStrLen) inMaxStrLen = strlen(MenuItem2);
	if (strlen(MenuItem3)>inMaxStrLen) inMaxStrLen = strlen(MenuItem3);
	if (strlen(MenuItem4)>inMaxStrLen) inMaxStrLen = strlen(MenuItem4);
	if (strlen(Label)+inMaxStrLen > 20)	Label[20-inMaxStrLen] = 0x00;

	set_font("F:asc8x21.vft");
	for(i=1; i<=inImamLineNumber; i++) display_at(21-inMaxStrLen, i, "|", CLR_EOL); // write_at("|", 1, 21-inMaxStrLen, i);
	display_at(1,inImamLineNumber/2+1, Label, NO_CLEAR);
	if (inImamLineNumber==16){
		display_at(22-strlen(MenuItem1), 4, MenuItem1, NO_CLEAR);
		display_at(22-strlen(MenuItem2), 7, MenuItem2, NO_CLEAR);
		display_at(22-strlen(MenuItem3), 10, MenuItem3, NO_CLEAR);
		display_at(22-strlen(MenuItem4), 13, MenuItem4, NO_CLEAR);
	} else {
		display_at(22-strlen(MenuItem1), 2, MenuItem1, NO_CLEAR);
		display_at(22-strlen(MenuItem2), 4, MenuItem2, NO_CLEAR);
		display_at(22-strlen(MenuItem3), 6, MenuItem3, NO_CLEAR);
		display_at(22-strlen(MenuItem4), 8, MenuItem4, NO_CLEAR);
	}
	set_font(ASC8X21_VFT);

	do {
		karakter = inImamWaitKey(inGetIdleTimeOut());
		if (karakter == 0x01 && strlen(MenuItem1)) {        //F1
			for(i=1; i<=inImamLineNumber; i++) 
				{display_at(21-inMaxStrLen, i, " ", CLR_EOL);
			         //return 1;
					ret=1;
			         break;
			     }
		} else if (karakter == 0x02 && strlen(MenuItem2)) { //F2
			for(i=1; i<=inImamLineNumber; i++) {display_at(21-inMaxStrLen, i, " ", CLR_EOL);
			         //return 2;
					ret=2;
			         break;
			     }
		} else if (karakter == 0x03 && strlen(MenuItem3)) { //F3
			for(i=1; i<=inImamLineNumber; i++) {display_at(21-inMaxStrLen, i, " ", CLR_EOL);
			         //return 3;
					ret=3;
			         break;
			     }
		} else if (karakter == 0x04 && strlen(MenuItem4)) { //F4
			for(i=1; i<=inImamLineNumber; i++){display_at(21-inMaxStrLen, i, " ", CLR_EOL);
			         //return 4;
					ret=4;
			         break;
			     }
		} else if (karakter == 0x1B) { //esc, no choice
			for(i=1; i<=inImamLineNumber; i++) {display_at(21-inMaxStrLen, i, " ", CLR_EOL);
			         //return 1;
					ret=0;
			         break;
			     }
		}
		ret2=ret;
		break;
	} while (1);
	return ret2;
}

int inImamInputNumber(char *szLabel, char *szOutput, int MaxSize)
{
	int karakter=0;
	char Number[22];
    int ret=VS_ESCAPE;
	set_font(ASC8X21_VFT);
	display_at(1, inImamLineNumber-1, szLabel, CLR_EOL);
	write_at("_", 1, 21, inImamLineNumber-1);

	memset(Number, 0x00, sizeof(Number));
	vdFlushKeyboardBuffer();
	do {
		karakter = inImamWaitKey(inGetIdleTimeOut());
		//LOG_PRINTFF((0x08L, "Karakter = [%d]", karakter));
		if (karakter >= 0x30 && karakter <= 0x39) {
			if ((strlen(Number)<21) &&  (strlen(Number)<MaxSize)) {
				Number[strlen(Number)] = karakter;
				if (strlen(Number)>0){
					write_at(Number, strlen(Number), 22-strlen(Number), inImamLineNumber-1);
				} else {
					write_at("_", 1, 21, inImamLineNumber-1);
				}
			}
		} else if (karakter==8) {
			if (strlen(Number)>0) {
				Number[strlen(Number)-1] = 0x00;	
				display_at(1, inImamLineNumber-1, szLabel, CLR_EOL);
				if (strlen(Number)>0){
					write_at(Number, strlen(Number), 22-strlen(Number), inImamLineNumber-1);
				} else {
					write_at("_", 1, 21, inImamLineNumber-1);
				}
			}
		} else if (karakter==13){
			strcpy(szOutput, Number);
			//return VS_SUCCESS;
			ret=VS_SUCCESS;
			break;
		} else if (karakter==27){
		       ret=VS_ESCAPE;
			break;
			//return VS_ESCAPE;
		} 
	} while (1);
	return ret;
}

int inImamInputNumberMasked(char *szLabel, char *szOutput, int MaxSize)
{
	int karakter=0;
	char Number[22];
    int ret=VS_ESCAPE;
	set_font(ASC8X21_VFT);
	display_at(1, inImamLineNumber-1, szLabel, CLR_EOL);
	write_at("_", 1, 21, inImamLineNumber-1);

	memset(Number, 0x00, sizeof(Number));
	vdFlushKeyboardBuffer();
	do {
		karakter = inImamWaitKey(inGetIdleTimeOut());
		//LOG_PRINTFF((0x08L, "Karakter = [%d]", karakter));
		if (karakter >= 0x30 && karakter <= 0x39) {
			if ((strlen(Number)<21) &&  (strlen(Number)<MaxSize)) {
				Number[strlen(Number)] = karakter;
				if (strlen(Number)>0){
					//write_at(Number, strlen(Number), 22-strlen(Number), inImamLineNumber-1);
					write_at("****", strlen(Number), 22-strlen(Number), inImamLineNumber-1);
				} else {
					write_at("_", 1, 21, inImamLineNumber-1);
				}
			}
		} else if (karakter==8) {
			if (strlen(Number)>0) {
				Number[strlen(Number)-1] = 0x00;	
				display_at(1, inImamLineNumber-1, szLabel, CLR_EOL);
				if (strlen(Number)>0){
					//write_at(Number, strlen(Number), 22-strlen(Number), inImamLineNumber-1);
					write_at("****", strlen(Number), 22-strlen(Number), inImamLineNumber-1);
				} else {
					write_at("_", 1, 21, inImamLineNumber-1);
				}
			}
		} else if (karakter==13){
			strcpy(szOutput, Number);
			//return VS_SUCCESS;
			ret=VS_SUCCESS;
			break;
		} else if (karakter==27){
		       ret=VS_ESCAPE;
			break;
			//return VS_ESCAPE;
		} 
	} while (1);
	return ret;
}


int inImamGetInstallments(TRANSACTION_OBJECT *pobTran)
{
	int inKey;
	int inResult = VS_SUCCESS;
	char szInstallments[5];
	char buff[30];
	int inPlan = 0;
	int inInstallments = 0;
	
	pobTran->srBRec.inInstallments = 0;
	pobTran->srBRec.inPlan = 0;

	if (inGetPaymentIndex()!=1 || inGetType()!=CREDIT_CARD || pobTran->srTRTRec.TransactionCode!=SALE) {
		return(VS_SUCCESS);
	}
/////////////////////////
//ONLINE REDEMPTION NOTE
//For penyederhanaan, akan dipakai variable2 SSP, yaitu
//inPlan = 4, 5  ==> Online Redemption
//inInstallments ==> Product Code(1-99)
//long lnDepositAmount  ==> to hold REDEEMED AMOUNT
//long lnAmountPerInstallment ==> to hold: REDEEMED POINT
////////////////////////

    vdClearNonTitleLines();
	if (fImamSSP()==1 && fImamOR()==1) {
		inKey = inBGMenuChoice("SALE?", "NORMAL", "SMART SPENDING", "ONLINE REDEMPT", "", 1);
		//inKey = obDisp.inDO_ChooseOne( NULL, "SALE?", " NORMAL~SMART SPENDING~ONLINE REDEMPT", 3, NULL_PFI );
	} else if (fImamSSP()==1) {
		inKey = inBGMenuChoice("SALE?", "NORMAL", "SMART SPENDING", "", "", 1);
		//inKey = obDisp.inDO_ChooseOne( NULL, "SALE?", " NORMAL~SMART SPENDING", 2, NULL_PFI );
	} else if (fImamOR()==1) {
		inKey = inBGMenuChoice("SALE?", "NORMAL", "ONLINE REDEMPT", "", "", 1);
		//inKey = obDisp.inDO_ChooseOne( NULL, "SALE?", " NORMAL~ONLINE REDEMPT", 2, NULL_PFI );
		if (inKey==2) inKey=3;
	} else {
		inCITICustDisplaySwipeCardInfo(pobTran);
		return (VS_SUCCESS);
	}

    if (inKey==VS_ESCAPE || inKey==0) return(VS_ESCAPE);	

	vdClearNonTitleLines();
	if (inKey == 1) {
		inCITICustDisplaySwipeCardInfo(pobTran);
		return (VS_SUCCESS); //means NO SSP or Point Redemption, normal payment
	} else if (inKey==2) {
		do {
			memset(szInstallments, 0x00, sizeof(szInstallments));
			//inResult = inEnterWithStrDefault((long) NULL, "SSP Term (2-12):", SCROLL_DISPLAY_TRUE, szInstallments, INPUT_NUMS,  2, NULL_PFI);
			inResult = inImamInputNumber("SSP Term (2-99):", szInstallments, 2);
			if (inResult==VS_ESCAPE) return (VS_ESCAPE);
			inInstallments = atoi(szInstallments);
			if ((inInstallments >= 2) && (inInstallments <= 99)) {
				break;
			} else {
				DisplayStatus("Out of range!");
				vdWarnBeep();
				SVC_WAIT(1000);
				vdClearNonTitleLines();
			} 
		} while (1);
	} else if (inKey==3) {
		do {
			memset(szInstallments, 0x00, sizeof(szInstallments));
			//inResult = inEnterWithStrDefault((long) NULL, "Product Code:", SCROLL_DISPLAY_TRUE, szInstallments, INPUT_NUMS,  2, NULL_PFI);
			inResult = VS_SUCCESS;
			if (inResult==VS_ESCAPE) return (VS_ESCAPE);
			//inInstallments = atoi(szInstallments);
			inInstallments = 90;
			if ((inInstallments >= 1) && (inInstallments <= 99)) {
				break;
			} else {
				DisplayStatus("Out of range!");
				vdWarnBeep();
				SVC_WAIT(1000);
				vdClearNonTitleLines();
			} 
		} while (1);
	} else {
		inCITICustDisplaySwipeCardInfo(pobTran);
		return (VS_SUCCESS); //means NO SSP or Point Redemption, normal payment
	}

	vdClearStatusMessage();

	if (inKey==2) {
		inPlan = inBGMenuChoice("SSP PLAN?", "PLAN 1", "PLAN 2", "PLAN 3", "", 1);
		//inPlan = obDisp.inDO_ChooseOne( NULL, "SSP PLAN?", " PLAN 1~PLAN 2~PLAN 3", 3, NULL_PFI );
		if (inPlan!=1 && inPlan!=2 && inPlan!=3) return(VS_ESCAPE);
	} else if (inKey==3) {
		inPlan = inBGMenuChoice("SKEMA?", "FULL POINT", "PARTIAL POINT", "", "", 1);
		//inPlan = obDisp.inDO_ChooseOne( NULL, "SKEMA?", " FULL POINT~PARTIAL POINT", 2, NULL_PFI );
		if (inPlan!=1 && inPlan!=2) return(VS_ESCAPE);
		inPlan = inPlan + 3;
	}

	pobTran->srBRec.inPlan = inPlan;
	pobTran->srBRec.inInstallments = inInstallments;
	vdClearNonTitleLines();
	inCITICustDisplaySwipeCardInfo(pobTran);

	if (inKey==2) {
		memset(buff, 0x00, sizeof(buff));
		sprintf(buff, "Term :             %02d", inInstallments);
   		vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
		vdCustScroll();
		memset(buff, 0x00, sizeof(buff));
		sprintf(buff, "Plan :             %02d", inPlan);
   		vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
	} else if (inKey==3) {
		memset(buff, 0x00, sizeof(buff));
		//sprintf(buff, "Product Code :     %02d", inInstallments);
   		//vdDisplayAt(1, 7, buff, CLR_EOL);
	}

	return(VS_SUCCESS);
}

int inImamGetTicketId (TRANSACTION_OBJECT *pobTran)  // for AirPort
{
    char szTicketID[TICKET_ID_SIZE + 1];
    int  inResult;

	if (!fGetImamAirlineTrx() || pobTran->srTRTRec.TransactionCode!=SALE) return (VS_SUCCESS);
    
	//inResult = inCPACEnterWithMessage(TICKET_ID_MSG, SCROLL_DISPLAY_TRUE, 7, 7, szTicketID, INPUT_ALNUMS, TICKET_ID_SIZE, inCPACValidateTicketID);
	vdScrollDisplay();
	do {
		memset(szTicketID, 0x00, sizeof(szTicketID));
		inResult = inImamInputNumber("FARE#:", szTicketID, TICKET_ID_SIZE);		
		if (inResult==VS_ESCAPE) return (VS_ESCAPE);
		if (strlen(szTicketID) >= 5) {
			break;
		} else {
			DisplayStatus("INVALID TICKET ID!");
			vdWarnBeep();
			SVC_WAIT(1000);
			DisplayStatus(" ");
		} 
	} while (1);
	if (inResult == VS_SUCCESS)											               
    {		 
		strcpy(pobTran->srBRec.szCustNum, szTicketID);
		pobTran->srBRec.fCustNum = VS_TRUE;
        inResult = VS_SUCCESS;
    }
    return(inResult);
}

int inImamGetPrivateLabel (TRANSACTION_OBJECT *pobTran) 
{
    char szPrivateLabel[PRIVATE_LABEL_SIZE + 1];
    int  inResult;
	int i=0;

	if (!fGetImamPrivateLabel() || pobTran->srTRTRec.TransactionCode!=SALE || pobTran->srBRec.fManual==VS_FALSE) return (VS_SUCCESS);
    
	vdScrollDisplay();
	do {
		memset(szPrivateLabel, 0x00, sizeof(szPrivateLabel));
		inResult = inImamInputNumber("PL/INV#:", szPrivateLabel, PRIVATE_LABEL_SIZE);		
		if (inResult==VS_ESCAPE) return (VS_ESCAPE);
		if (strlen(szPrivateLabel) >= 4) {
			break;
		} else {
			DisplayStatus("INVALID PL/INV!");
			vdWarnBeep();
			SVC_WAIT(1000);
			DisplayStatus(" ");
		} 
	} while (1);
	if (inResult == VS_SUCCESS){		 
		for (i=0; i<strlen(szPrivateLabel); i++) { szPrivateLabel[i] = szPrivateLabel[i] + 192; } //make it EBCDIC
		strcpy(pobTran->srBRec.szCustNum, szPrivateLabel);
		pobTran->srBRec.fCustNum = VS_TRUE;
        inResult = VS_SUCCESS;
    }
    return(inResult);
}

int inImamGetCVV2(TRANSACTION_OBJECT* pobTran) 
{
    char szCVV2Code[CVV2_SIZE + 1];
    int  inResult;
    char* chNull = 0;
/*
    if (inGetCVV_II() == NO_CVV2 || (pobTran->srBRec.fManual == VS_FALSE) || pobTran->srBKey.fOffline)
        return(VS_SUCCESS);
    if ((inGetCVV_II() == CVV2_CARD_NOT_PRESENT) && fGetCardPresent() && pobTran->fCardPresent)
        return(VS_SUCCESS);

    if ((inGetCVV_II() == CVV2_CARD_NOT_PRESENT) && (fGetCardPresent() == VS_FALSE)) {  //all card is set to GetCardPresent==0
        vdDisplayMessageFromFile(CDT_CVV2_CONFLICT_ERR_MSG, ERROR_MSG);
        return(VS_ESCAPE);
    } 
	if (inGetCVV_II() == CVV2_CARD_NOT_PRESENT){
		return(VS_ESCAPE);
	}
*/
	if (((inGetCVV_II() == CVV2_CARD_EITHER) && (pobTran->srBRec.fManual) && (!pobTran->srBKey.fOffline)) ||
		((pobTran->srBRec.fManual==VS_TRUE) && (fGetImamManual4DBC())) ||
		((pobTran->srBRec.fManual==VS_FALSE) && (fGetImamSwipe4DBC()))
		){
	} else {
		return VS_SUCCESS;
	}

	if ((inGetCVV_II() == CVV2_CARD_EITHER) && (pobTran->srBRec.fManual) && (!pobTran->srBKey.fOffline)) {
		vdScrollDisplay();
		do {
			memset(szCVV2Code, 0x00, sizeof(szCVV2Code));
			inResult = inImamInputNumber("CVV II:", szCVV2Code, CVV2_SIZE);		
			if (inResult==VS_ESCAPE) return (VS_ESCAPE); 
			if ((strlen(szCVV2Code)==CVV2_SIZE) || (strlen(szCVV2Code)==0)){
				break;
			} else {
				DisplayStatus("INVALID VALUE!");
				vdWarnBeep();
				SVC_WAIT(1000);
				DisplayStatus(" ");
			} 
		} while (1);
	} 
	if ( ((pobTran->srBRec.fManual==VS_TRUE) && (fGetImamManual4DBC())) ||
		 ((pobTran->srBRec.fManual==VS_FALSE) && (fGetImamSwipe4DBC()))
		){
		vdScrollDisplay();
		do {
			memset(szCVV2Code, 0x00, sizeof(szCVV2Code));
			inResult = inImamInputNumberMasked("AMEX 4DBC:", szCVV2Code, CVV2_SIZE);		
			if (inResult==VS_ESCAPE) return (VS_ESCAPE); 
			if (strlen(szCVV2Code)==CVV2_SIZE){
				break;
			} else {
				DisplayStatus("INVALID VALUE!");
				vdWarnBeep();
				SVC_WAIT(1000);
				DisplayStatus(" ");
			} 
		} while (1);
	}
	if (inResult == VS_SUCCESS){		 
		if (strlen(szCVV2Code)){
            strcpy(pobTran->szCVV2Value, szCVV2Code);
			pobTran->chCVV2PresenceIndicator = CVV2_VALUE_PRESENCE;
            inResult = VS_SUCCESS;
		} else {
            if ((inResult = obDisp.inDO_ChooseOne(chNull, (char *) pchGetMsg(CODE_ON_BACK_MSG), (char *) pchGetMsg(NO_XREAD_MSG), 2, NULL_PFI)) == KEY_CODE_ON_BACK_NO) {
				LOG_PRINTFF((0x08L, "CVV2_NOT_ON_BACK"));
				pobTran->chCVV2PresenceIndicator = CVV2_NOT_ON_BACK;
                strcpy(pobTran->szCVV2Value, "");
                inResult = VS_SUCCESS;
            } else if (inResult == KEY_CODE_ON_BACK_XREAD) {
				LOG_PRINTFF((0x08L, "CVV2_ILLEGIBLE"));
                pobTran->chCVV2PresenceIndicator = CVV2_ILLEGIBLE;
                strcpy(pobTran->szCVV2Value, "");
                inResult = VS_SUCCESS;
            } else {
				LOG_PRINTFF((0x08L, "GET CVV2 ERROR"));
                inResult = VS_ERROR;
            }
		}
    }
    return(inResult);
}

int inCPACValidateTicketID (char *szString)
{
	if ( strlen(szString) < 5 || strlen(szString) > TICKET_ID_SIZE)
	{
	    vdSGErrorMessage(INVALID_ENTRY_MSG);
    	return (VS_ERR);
	}	
    return(VS_SUCCESS);
}

int inImamSetParmDownConfig(TRANSACTION_OBJECT *pobTran)
{
    int inResult=1;
	char buff[128];
	char chImamBuffer[128];
	int  inRes;
	#ifdef IMAM_BNI
	
	int  i;
	#endif

	memset(chImamBuffer, 0x00, sizeof(chImamBuffer));
	inRes = SVC_INFO_SERLNO(chImamBuffer);
	chImamBuffer[11] = 0x00;
/*
	for (i=0; i<strlen(chImamBuffer); i++) {
		if (!isdigit(chImamBuffer[i])) {
			strcpy(&chImamBuffer[i], &chImamBuffer[i+1]);
			i--;
		}
	}
	if (strlen(chImamBuffer)>9) {
		strcpy(chImamBuffer, &chImamBuffer[strlen(chImamBuffer)-9]);
	}
	if (strlen(chImamBuffer)<9) {
		DisplayStatus("Error Get SN");
		SVC_WAIT(2000);
		return (VS_ESCAPE);
	}
*/
	memset(buff, 0x00, sizeof(buff));
	sprintf(buff, "S/N  : %s", chImamBuffer); 
	vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
	if (inResult>=0) inResult = put_env("*ZT", chImamBuffer, strlen(chImamBuffer));
	
	if (inUseSNasTID()==0) {
		vdScrollDisplay();
		memset(buff, 0x00, sizeof(buff));
		if (inResult>=0) inResult = InputString("TID  : ", buff);
		if (inResult>=0) inResult = put_env("*ZT", buff, strlen(buff));
	}

	vdScrollDisplay();
	memset(buff, 0x00, sizeof(buff));
	if (inResult>=0) inResult = InputString("Phone: ", buff);
	if (buff[0] != 'T') {
		memmove(&buff[1], buff, strlen(buff));
		buff[0] = 'T';
	}
	if (inResult>=0) inResult = put_env("*ZP", buff, strlen(buff));
	
	vdScrollDisplay();
	DisplayStatus("Wait...");

//	if (SVC_INFO_MODULE_ID(SVC_INFO_PORT_MODEM())==3){
		{
			char szApplName[20];
			memset(szApplName, 0x00, sizeof(szApplName));
			if (inMAMAvailable) {
//				strcpy(szApplName, "VSP31AMEX");
//				strcpy(szApplName, "VSP31K6D");
//				strcpy(szApplName, "VSP31EMV");
//				strcpy(szApplName, "VEMVDEV");
//				strcpy(szApplName, "OSP31EMV");
			//	strcpy(szApplName, "BNI1404A");
			// OMNI =BNI1404O
                     //  VX   =BNI1404V
				strcpy(szApplName, "BNI1904V");

			} else {
//				strcpy(szApplName, "SP31AMEX");
//				strcpy(szApplName, "SP31K6D");
//				strcpy(szApplName, "VSP31EMV");
//				strcpy(szApplName, "EMVDEV");
//				strcpy(szApplName, "OSP31EMV");
			//	strcpy(szApplName, "BNI1404A");
				strcpy(szApplName, "BNI1904V");

			}
			if (inResult>=0) inResult = put_env("*ZA", szApplName, strlen(szApplName));
		}
#ifdef __arm
		if (inResult>=0) inResult = put_env("*ZINIT", "ATE1M0V0&D2&Q6%E0%C1&K0&J3S0=1", strlen("ATE1M0V0&D2&Q6%E0%C1&K0&J3S0=1"));
		if (inResult>=0) inResult = put_env("*ZRESP", "16", strlen("16"));
		if (inResult>=0) inResult = put_env("*ZRESET", "atz0", strlen("atz0"));
		if (inResult>=0) inResult = put_env("*ZR", "6", strlen("6"));
#else 
		if (SVC_INFO_MOD_ID() == ASPEN_MODEM_ID) {//edi - Modem fix bug
			if (inResult>=0) inResult = put_env("*ZINIT", "ATM0V0&D2", strlen("ATM0V0&D2"));
		} else {
			if (inResult>=0) inResult = put_env("*ZINIT", "ATE0V0K0S0=1", strlen("ATE0V0K0S0=1"));
		}
		if (inResult>=0) inResult = put_env("*ZRESP", "10", strlen("10"));
		if (inResult>=0) inResult = put_env("*ZRESET", "atz", strlen("atz"));
		if (inResult>=0) inResult = put_env("*ZR", "2", strlen("2"));
#endif
		if (inResult>=0) inResult = put_env("*ZSWESC", "+++", strlen("+++"));
//	}
    if (inResult>=0) return (VS_SUCCESS);
    return (VS_ESCAPE);
}

int inImamSetFullDownConfig(TRANSACTION_OBJECT *pobTran)
{
    int inResult=1;
	char buff[128];

	char chImamBuffer[128];
	int  inRes;
	#ifdef IMAM_BNI
	int  i;
	#endif

	memset(chImamBuffer, 0x00, sizeof(chImamBuffer));
	inRes = SVC_INFO_SERLNO(chImamBuffer);
	chImamBuffer[11] = 0x00;
/*
	for (i=0; i<strlen(chImamBuffer); i++) {
		if (!isdigit(chImamBuffer[i])) {
			strcpy(&chImamBuffer[i], &chImamBuffer[i+1]);
			i--;
		}
	}
	if (strlen(chImamBuffer)>9) {
		strcpy(chImamBuffer, &chImamBuffer[strlen(chImamBuffer)-9]);
	}
	if (strlen(chImamBuffer)<9) {
		DisplayStatus("Error Get SN");
		SVC_WAIT(2000);
		return (VS_ESCAPE);
	}
*/
	memset(buff, 0x00, sizeof(buff));
	sprintf(buff, "S/N  : %s", chImamBuffer); 
	vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
	if (inResult>=0) inResult = put_env("*ZT", chImamBuffer, strlen(chImamBuffer));
	
	if (inUseSNasTID()==0) {
		vdScrollDisplay();
		memset(buff, 0x00, sizeof(buff));
		if (inResult>=0) inResult = InputString("TID  : ", buff);
		if (inResult>=0) inResult = put_env("*ZT", buff, strlen(buff));
	}

	vdScrollDisplay();
	memset(buff, 0x00, sizeof(buff));
	if (inResult>=0) inResult = InputString("Phone: ", buff);
	if (buff[0] != 'T') {
		memmove(&buff[1], buff, strlen(buff));
		buff[0] = 'T';
	}
	if (inResult>=0) inResult = put_env("*ZP", buff, strlen(buff));
/*
	vdScrollDisplay();
	memset(buff, 0x00, sizeof(buff));
	if (inResult>=0) inResult = InputString("Appl : ", buff);
	if (inResult>=0) inResult = put_env("*ZA", buff, strlen(buff));
*/
	vdScrollDisplay();
	DisplayStatus("Wait...");

//	if (SVC_INFO_MODULE_ID(SVC_INFO_PORT_MODEM())==3){
		{
			char szApplName[20];
			memset(szApplName, 0x00, sizeof(szApplName));
			if (inMAMAvailable) {
//				strcpy(szApplName, "VSP31AMEX");
//				strcpy(szApplName, "VSP31K6D");
//				strcpy(szApplName, "VSP31EMV");
//				strcpy(szApplName, "VEMVDEV");
//				strcpy(szApplName, "OSP31EMV");
				strcpy(szApplName, "BNI1404A");
			} else {
//				strcpy(szApplName, "SP31AMEX");
//				strcpy(szApplName, "SP31K6D");
//				strcpy(szApplName, "VSP31EMV");
//				strcpy(szApplName, "EMVDEV");
//				strcpy(szApplName, "OSP31EMV");
				strcpy(szApplName, "BNI1404A");
			}
			if (inResult>=0) inResult = put_env("*ZA", szApplName, strlen(szApplName));
		}
#ifdef __arm
		if (inResult>=0) inResult = put_env("*ZINIT", "ATE1M0V0&D2&Q6%E0%C1&K0&J3S0=1", strlen("ATE1M0V0&D2&Q6%E0%C1&K0&J3S0=1"));
		if (inResult>=0) inResult = put_env("*ZRESP", "16", strlen("16"));
		if (inResult>=0) inResult = put_env("*ZRESET", "atz0", strlen("atz0"));
		if (inResult>=0) inResult = put_env("*ZR", "6", strlen("6"));
#else 
		if (SVC_INFO_MOD_ID() == ASPEN_MODEM_ID) {//edi - Modem fix bug
			if (inResult>=0) inResult = put_env("*ZINIT", "ATM0V0&D2", strlen("ATM0V0&D2"));
		} else {
			if (inResult>=0) inResult = put_env("*ZINIT", "ATE0V0K0S0=1", strlen("ATE0V0K0S0=1"));
		}
		if (inResult>=0) inResult = put_env("*ZRESP", "10", strlen("10"));
		if (inResult>=0) inResult = put_env("*ZRESET", "atz", strlen("atz"));
		if (inResult>=0) inResult = put_env("*ZR", "2", strlen("2"));
#endif
		if (inResult>=0) inResult = put_env("*ZSWESC", "+++", strlen("+++"));
//	}

    if (inResult>=0) return (VS_SUCCESS);
    return (VS_ESCAPE);
}

int inImamCustScroll(TRANSACTION_OBJECT *pobTran)
{
	vdDisplayAt(1, inImamLineNumber, " ", CLR_EOL);
	vdCustScroll();
	return VS_SUCCESS;
}



//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////

int inImamCustGetPartialPointAmount(TRANSACTION_OBJECT *pobTran)
{
	char szAmt[AMT_SIZE + 1];
	char szDisplaySymbol[CUR_SYMBOL_SIZE + 1];
    int  inResult;

	memset (szAmt, 0, sizeof(szAmt));
	strcpy (szDisplaySymbol,szGetCurSymbol());
	if (pobTran->srBRec.inPlan>=4 && pobTran->srTRTRec.TransactionCode==SALE) {  //LIEM for PARTIAL POINT
		if (pobTran->srBRec.inPlan==4) return (VS_SUCCESS);
		vdCustDisplayPrompt (POINT_MSG, VS_TRUE);
		if ((inResult = inImamCustGetAmount(szAmt, 1L, 999999999L, szDisplaySymbol, POINT_MSG)) != VS_SUCCESS)
			return(inResult);
	}
    pobTran->srBRec.lnDualAmount = atol(szAmt);
	return (VS_SUCCESS);
}

int inImamCustGetBaseAmount(TRANSACTION_OBJECT* pobTran) {
    long lOpenAmount;
    int inResult,
    inTranCode; //, inAllow; cpac_2.2a
    char szDisplaySymbol[CUR_SYMBOL_SIZE + 1],
    szAmount[AMT_SIZE + 1];
    char szBuffer[21 + 1];
    inTranCode = pobTran->srBRec.inCode;
    lOpenAmount = 0L;

    vdGetMessageFromFile(EMPTY_STR_ERR_MSG, szBuffer);
    if (getgrid() == 0)
        vdDisplayAt(1, 4, szBuffer, CLR_EOL);//LENIN 2.2B
    else
        vdDisplayAt(1, inImamLineNumber, szBuffer, CLR_EOL);//LENIN 2.2B
    
	//vdCustDisplayPrompt(AMT_MSG, VS_TRUE); 

    BT_TRACE(' ', "Enter Base Amt");

    szAmount[0] = '\0';

    if (inTranCode == PRE_AUTH) {
        lOpenAmount = inGetOpenTabDAmt();
        lOpenAmount = lOpenAmount * 100;
        sprintf(szAmount, "%ld", lOpenAmount);
    }
    strcpy(szDisplaySymbol, szGetCurSymbol());
    sprintf(pobTran->srBRec.szIssueNumber, "%02d", inGetIssuerNumber() - 1);//LENIN

	if ((fGetImamAirlineTrx()) && (pobTran->srTRTRec.TransactionCode==SALE)) {  // for AIRLINE
		vdCustDisplayPrompt (FARE_MSG, VS_TRUE);
		if ((inResult = inImamCustGetAmount(szAmount, 1L, 999999999L, szDisplaySymbol, FARE_MSG)) != VS_SUCCESS)
			return(inResult);
	} else if (pobTran->srBRec.inPlan == 4) { // for FULL POINT
		//vdCustDisplayPrompt (POINT_MSG, VS_TRUE); 
		vdCustDisplayPrompt (AMT_MSG, VS_TRUE); 
		if ((inResult = inImamCustGetAmount(szAmount, 1L, 999999999L, szDisplaySymbol, POINT_MSG)) != VS_SUCCESS)
			return(inResult);
	} else {
		vdCustDisplayPrompt (AMT_MSG, VS_TRUE); //Normal or PARTIAL POINT
		if ((inResult = inImamCustGetAmount(szAmount, 1L, 999999999L, szDisplaySymbol, AMT_MSG)) != VS_SUCCESS)
			return(inResult);
	}

    pobTran->srBRec.lnBaseTransactionAmount = atol(szAmount);

    //LENIN 2.2     inAllow = inTotalTransAmtAlwd(pobTran);  //leo_apr27 added
    //LENIN 2.2 if (inAllow == VS_ERR) return (VS_ERR);


    //  inUpdate = inCPACTransAmtUpdate(pobTran);   //leo_apr27 added
    //  if (inUpdate == VS_ERR) return (VS_ERR);    //commented may2400 does not work when any txn fails!!!
    // negative test case!          
    return (VS_SUCCESS);
}

int inImamCustGetTip(TRANSACTION_OBJECT* pobTran) 
{
	char szAmt[AMT_SIZE + 1], szDisplaySymbol[CUR_SYMBOL_SIZE + 1];
	#ifndef IMAM_BNI
	char szTempAmt[AMT_SIZE + 1];
	#endif
	int inRetVal,
	inAllow;
	int inSurcharge;
	long lnTempTip,
	lnTempBaseAmt;

	inSurcharge = 0;
	pobTran->srBRec.fTipEntered = VS_FALSE;
	memset(szAmt, 0, sizeof(szAmt));

	if (fGetImamAirlineTrx() && pobTran->srTRTRec.TransactionCode==SALE) {  //LIEM for AIRLINE
		pobTran->srBRec.fTipEntered = VS_TRUE;
        vdCustDisplayPrompt (NON_FARE_MSG, VS_TRUE); // scroll here
		strcpy (szDisplaySymbol,szGetCurSymbol());
		if ((inRetVal = inImamCustGetAmount(szAmt, 0L, pobTran->srBRec.lnBaseTransactionAmount, szDisplaySymbol, NON_FARE_MSG)) != VS_SUCCESS )
		{
			if (inRetVal == VS_ESCAPE) return(inRetVal);
			vdCustDisplayMessageFromFile( VALIDATE_ERR_MSG, WARNING_MSG);
			vdCustDisplayMessageFromFile( EMPTY_STR_ERR_MSG, STATUS_MSG);
			return(inRetVal);
		}		
		pobTran->srBRec.lnTipAmount = atol(szAmt);
		inAllow = inTotalTransAmtAlwd(pobTran); 
		if (inAllow == VS_ERR) return (VS_ERR);
		return (VS_SUCCESS);
	}

	if (pobTran->fTipAdjust) 
	{
		pobTran->srBRec.lnOldTotalTransactionAmount = pobTran->srBKey.lnTotalOfTransactionAmount;
		pobTran->srBRec.lnOldTipAmount = pobTran->srBRec.lnTipAmount;
	}

	if (inGetTipProcessing()==2) {  // to improve tip_adjust / tip prrompt and print behave
		pobTran->srBRec.lnTipAmount = 0L;
		pobTran->srBRec.fTipEntered = VS_TRUE;
	}

	if ((inGetTipPercent() > 0) && (inGetTipProcessing() > TIP_OFF)){
   		pobTran->srBRec.fTipEntered = VS_TRUE;
   		inRetVal = inComputePercent((long )inGetTipPercent(),szAmt, pobTran->srBRec.lnBaseTransactionAmount,TIP_FORMAT);
   		pobTran->srBRec.lnTipAmount = atol(szAmt);
	  	if (inRetVal != VS_SUCCESS) return(inRetVal); 
    }

	if ((inGetTipProcessing() == TIP_ON_PROMPT) 
	//||((inGGCode() == SALE && inGetTipProcessing() > TIP_OFF)  // : Disable this 2 line so debit card will not always ask for pin
	//&& (pobTran->srBRec.inTranCardType == DEBIT_CARD ||pobTran->srBRec.inTranCardType == EBT_CARD)) 
	){
		BT_TRACE(' ', "Enter Tip Amt");
		pobTran->srBRec.fTipEntered = VS_TRUE;
    	vdCustDisplayPrompt (TIP_AMT_MSG, VS_TRUE); // scroll here
		while (VS_TRUE){
			if (inGetTipPercent() == 0)  
				memset (szAmt,0,sizeof(szAmt));
			strcpy (szDisplaySymbol,szGetCurSymbol());
#ifdef TIP_MAX_LIMIT_DEFINED 				
			if ( (inRetVal = inImamCustGetAmount(szAmt, 0L, pobTran->srBRec.lnBaseTransactionAmount,	szDisplaySymbol, TIP_AMT_MSG)) != VS_SUCCESS )
#else  
			if ( (inRetVal = inImamCustGetAmount(szAmt, 0L, 999999999L, szDisplaySymbol, TIP_AMT_MSG)) != VS_SUCCESS )
#endif /* CITI_PHIL added citiphil_1.4_DON_DSC_28FEB NO LIMIT FOR TIP ADJUST */                            
			{
				if (inRetVal == VS_ESCAPE) return(inRetVal);
				vdCustDisplayMessageFromFile( VALIDATE_ERR_MSG, WARNING_MSG);
				vdCustDisplayMessageFromFile( EMPTY_STR_ERR_MSG, STATUS_MSG);
				return(inRetVal);
			}		
            lnTempTip = atol(szAmt);
            lnTempBaseAmt = pobTran->srBRec.lnBaseTransactionAmount;
#ifndef  CITI_PHIL
	???
			if((lnTempTip >= lnTempBaseAmt) ||((inGGCode() == PRE_COMP) && 
			  ((lnTempTip + lnTempBaseAmt) > pobTran->srBRec.lnOldTotalTransactionAmount)))
#endif/* CITI_PHIL */
				/*
					This is done as CitiBank Philippines wants to do Pre-Auth just as an Auth Only
					and Pre-comp just as an offline. There is a situation where Pre-Auth is done in
					one terminal and completion in another terminal, the old amount can never be
					used for verification... Vipin_27feb_Manila
				*/
#ifndef CITI_PHIL
	???
   			if(lnTempTip >= lnTempBaseAmt){	// still give chance even if tip > = amount
				vdCustDisplayMessageFromFile( OUT_OF_RANGE_ERR_MSG, WARNING_MSG);
				vdCustDisplayMessageFromFile( EMPTY_STR_ERR_MSG, STATUS_MSG);
				vdCustDisplayPrompt (TIP_AMT_MSG, VS_FALSE); // Don't scroll here
				memset (szAmt,0,sizeof(szAmt));
				continue;
			}
#endif /* CITI_PHIL Don_DSC_27feb_Citi_phil removed as no limit to Tip amt.*/
				//Kelvin_F2 --- start: add Excess Tip % checking
#ifdef HKGM
		???
	   		if(fExcessiveTip(pobTran,lnTempTip)){
		   		vdCustDisplayMessageFromFile(TOO_MUCH_TIP_MSG, WARNING_MSG);
		   		vdCustDisplayPrompt (TIP_AMT_MSG, VS_FALSE);
		   		memset (szAmt,0,sizeof(szAmt));
		   		continue;
	   		}
#endif /* HKGM */
			//Kelvin_F2 --- end: add Excess Tip % checking
			pobTran->srBRec.lnTipAmount = atol(szAmt);
	    	inAllow = inTotalTransAmtAlwd(pobTran);  //leo_apr27 added
			if (inAllow == VS_ERR) return (VS_ERR);
			break;
		}
	}

	return(VS_SUCCESS);
} /* End of inNovaGetTip () */


int inImamCustGetAmount(char* szAmount,long lnMin,long lnMax,char* pszDisplaySymbol,long lnMsgId) {
    int x1,
    y1,
    x2,
    y2,
    inResult,
    inRowLim;

    char* szAmtFormat = szGetAmountFormat();
    char szCurSym[CUR_SYMBOL_SIZE + 1];
    int inDigitsInAmt = strlen(szAmtFormat);
    int inXPos;
    int inDigitCount,
    n,
    max;
    int inInputLine;
    int inMaxDigits;
    WIN_INFO wiCur8x21Win;
    int inGrid;
    char szTestAmt[12 + 1];

    szCurSym[0] = '\0';
    strcpy(szCurSym, pszDisplaySymbol);

    inGrid = getgrid();
    if (inGrid == 0)
        inInputLine = 4;
    else
        inInputLine = inImamLineNumber-1;

    for (inDigitCount = 0, n = 0, max = strlen(szAmtFormat); n < max; n++) {
        if (toupper(szAmtFormat[n]) == 'N')
            inDigitCount++;
    }

    inRowLim = inGetRowLim();   

    if (inGrid == 0) {
        vdCustCalculateCoord(GRID_4x8_TO_8x21, &inRowLim, &inInputLine);   // making it all 8x21

        //#ifdef TLFB           //(Saritha_b1  Moving out TLFB Switch)
        //inInputLine=6;
        //#else
        inInputLine = 8;  // overriding the input line to make it look better
        //#endif /* TLFB */
    }

    inXPos = inRowLim - inDigitsInAmt + 1;
    wherewin(&x1, &y1, &x2, &y2);

    /* Setup entry window */
    wiCur8x21Win.inLeft = inXPos;
    wiCur8x21Win.inTop = inInputLine;
    wiCur8x21Win.inRight = inRowLim;
    wiCur8x21Win.inBottom = inInputLine;

    inMaxDigits = inGetCPACMaxAmtEntryDigits();
    if (inMaxDigits > 10)
        inMaxDigits = 10;
    do {
        if (obDisp.blActionFontASC8x21)
            window(wiCur8x21Win.inLeft, wiCur8x21Win.inTop, wiCur8x21Win.inRight, wiCur8x21Win.inBottom);
        inResult = inImamEnterNumber(&wiCur8x21Win, szAmount, inMaxDigits, szCurSym, szAmtFormat);
        if (obDisp.blActionFontASC8x21)
            window(obDisp.inHomeCol, obDisp.inTitleLine, inRowLim, obDisp.inCharsPerColumn);
        if (inResult < 0)
            return(inResult);
        vdPurgeStrofChars(szAmount, ".,");

		LOG_PRINTFF((0x08L, "Entered Amount: [%s]", szAmount)); //LIEM
        memset(szTestAmt, 0x00, sizeof(szTestAmt));
        strcpy(szTestAmt, "2147483646");

        if (strcmp(szAmount, szTestAmt) > 0) {
            vdCustDisplayMessageFromFile(OUT_OF_RANGE_ERR_MSG, WARNING_MSG);
            vdCustDisplayMessageFromFile(EMPTY_STR_ERR_MSG, STATUS_MSG);
            vdCustDisplayPrompt(lnMsgId, VS_FALSE);
            memset(szAmount, 0, sizeof(szAmount));
            continue;
        }

        if ((str2long(szAmount) >= lnMin) && (str2long(szAmount) <= lnMax)) {
			LOG_PRINTFF((0x08L, "Amount %ld <= %ld <= %ld", lnMin, str2long(szAmount), lnMax)); //LIEM
            break;
		}
        vdCustDisplayMessageFromFile(OUT_OF_RANGE_ERR_MSG, WARNING_MSG);
        vdCustDisplayMessageFromFile(EMPTY_STR_ERR_MSG, STATUS_MSG);
        vdCustDisplayPrompt(lnMsgId, VS_FALSE);  // LENIN 2.2 
        memset(szAmount, 0, sizeof(szAmount));
    } while (1);

    window(x1, y1, x2, y2);
    return (VS_SUCCESS);
}

int inImamEnterNumber(WIN_INFO* psr_wi8x21Win,char* szResponseString,int inMaxChars,char* szCurSym,char* szAmtFormat) {
    int inCharsEntered,
    inInitialKeyHit = TRUE;
    int inFieldVisibleWidth;
    int inResult;
    char chChar;
    char szInternalBuffer[FORMATTED_AMOUNT_SIZE + 1];
    char szLocBuf[1 + 1];
    VS_BOOL fNegativeValue;

    /** /pdebug(("--inEnterNumber--"));*/

    memset(szLocBuf, NULL_CH, sizeof(szLocBuf));
    inFieldVisibleWidth = psr_wi8x21Win->inRight - psr_wi8x21Win->inLeft + 1;
    strlcpy(szInternalBuffer, szResponseString, FORMATTED_AMOUNT_SIZE);
    if (szInternalBuffer[0] == '-')
        fNegativeValue = VS_TRUE;
    else
        fNegativeValue = VS_FALSE;
    purge_char(szInternalBuffer, ',');//chRadixDelimiter);
    purge_char(szInternalBuffer, '.');//chSeparatorDelimiter);
    purge_char(szInternalBuffer, '-');
    inCharsEntered = strlen(szInternalBuffer);

    formatAmt(szResponseString, szInternalBuffer, szCurSym, szAmtFormat, VS_FALSE);
    vdImamEntryDisplayAt(psr_wi8x21Win, inFieldVisibleWidth - strlen(szResponseString) + 1, obDisp.inTitleLine, szResponseString, CLR_EOL);

    while (1) {
        chChar = (char) inImamWaitKey(inGetIdleTimeOut());

        if (chChar == KEY_CR || chChar == KEY_CANCEL)
            break;

        /** /pdebug(("chChar = %02Xh", chChar));*/
        /** /pdebug(("inCharsEntered = %d", inCharsEntered));*/

        if (inInitialKeyHit && inCharsEntered && (isdigit(chChar))) {
            /** /pdebug(("Clearing Value"));*/
            szInternalBuffer[0] = chChar;
            szInternalBuffer[1] = 0;
            formatAmt(szResponseString, szInternalBuffer, szCurSym, szAmtFormat, VS_FALSE);
            vdImamEntryDisplayAt(psr_wi8x21Win, obDisp.inHomeCol, obDisp.inTitleLine, szLocBuf, CLR_EOL); /* Clear any old entry off display */
            vdImamEntryDisplayAt(psr_wi8x21Win, inFieldVisibleWidth - strlen(szResponseString) + 1, obDisp.inTitleLine, szResponseString, CLR_EOL);
            inCharsEntered = 0;
        }

        szInternalBuffer[inCharsEntered] = chChar;
        switch (chChar) {
        case    KEY_BS:
            if (inCharsEntered) {
                vdImamEntryDisplayAt(psr_wi8x21Win, inFieldVisibleWidth - strlen(szResponseString) + 1, obDisp.inCharsPerColumn - 1, "  ", NO_CLEAR);
                --inCharsEntered;
            } else
                vdBeep();
            inInitialKeyHit = FALSE;
            break;

            // BJD: KEY_CLR processing (begin)
        case    KEY_CLR:
            if (inCharsEntered) {
                szInternalBuffer[0] = '\0';
                inCharsEntered = 0;
                formatAmt(szResponseString, szInternalBuffer, szCurSym, szAmtFormat, VS_FALSE);
                vdImamEntryDisplayAt(psr_wi8x21Win, obDisp.inHomeCol, obDisp.inTitleLine, szLocBuf, CLR_EOL); /* Clear any old entry off display */
                vdImamEntryDisplayAt(psr_wi8x21Win, inFieldVisibleWidth - strlen(szResponseString) + 1, obDisp.inTitleLine, szResponseString, CLR_EOL);
            } else    // No characters entered yet
                vdBeep();
            break;
            // BJD: KEY_CLR processing (end)

        case    '0':
            if (inCharsEntered == 0)
                --inCharsEntered;

        case    '1':
        case    '2':
        case    '3':
        case    '4':
        case    '5':
        case    '6':
        case    '7':
        case    '8':
        case    '9':
            if (inCharsEntered < inMaxChars)
                ++inCharsEntered;
            else
                vdBeep();
            inInitialKeyHit = FALSE;
            break;

        case    KEY_ALP:
            /** /pdebug(("KEY_ALP"));*/
            if (fNegativeValue == VS_FALSE) {
                if (inCharsEntered < inMaxChars)
                    fNegativeValue = VS_TRUE;
                else
                    vdBeep();
            } else {
                fNegativeValue = VS_FALSE;
                vdImamEntryDisplayAt(psr_wi8x21Win, inFieldVisibleWidth - strlen(szResponseString) + 1, obDisp.inCharsPerColumn - 1, "  ", NO_CLEAR);
            }
            inInitialKeyHit = FALSE;
            break;

        default:
            vdBeep();
        }
        szInternalBuffer[inCharsEntered] = '\0';
        /** /pdebug(("szInternalBuffer = %s", szInternalBuffer));*/

        formatAmt(szResponseString, szInternalBuffer, szCurSym, szAmtFormat, VS_FALSE);
        vdImamEntryDisplayAt(psr_wi8x21Win, inFieldVisibleWidth - strlen(szResponseString) + 1, obDisp.inTitleLine, szResponseString, CLR_EOL);
        /** /pdebug(("szResponseString = %s", szResponseString));*/
    }
    /** /pdebug(("chChar = %02Xh", chChar));*/

    //if (!gu_clr_state()) -- key is already read from kbd buffer in inWaitKey() so is not pending anymore
    if (chChar != KEY_CANCEL) {
        formatAmt(szResponseString, szInternalBuffer, "", szAmtFormat, VS_FALSE);   // Reformats output with no currency for processing!
        inResult = strlen(szResponseString);
    } else
        inResult = VS_ESCAPE;

    /** /pdebug(("inResult = %d", inResult));*/
    return(inResult);
}

int inImamGetInvNum(TRANSACTION_OBJECT* pobTran) 
{
    char szUsrInvNum[CPAC_USR_INV_NUM_SIZE + 1];
    int inResult,
    inGrid;

	if ((pobTran->srTRTRec.TransactionCode==REFUND || pobTran->srTRTRec.TransactionCode==REFUND_DEBIT) && 
		(!fGetImamRefundApprCode())) {
		return (VS_SUCCESS);
	}
/*
	if (pobTran->srBRec.inTranCardType == DEBIT_CARD){
	} else {
		return (VS_SUCCESS);
	}
*/
    inGrid = getgrid();
	
    if (inGrid == 0)
        inResult = inCPACEnterWithMessage(INVOICE_MSG, SCROLL_DISPLAY_FALSE, 3, 6, szUsrInvNum, INPUT_ALNUMS, CPAC_USR_INV_NUM_SIZE, inValidateString);
    else
        inResult = inCPACEnterWithMessage(INVOICE_MSG, SCROLL_DISPLAY_TRUE, inImamLineNumber-1, inImamLineNumber-1, szUsrInvNum, INPUT_ALNUMS, CPAC_USR_INV_NUM_SIZE, inValidateString);    

	if (inResult == VS_ESCAPE) // CLEAR key processing.
        return (VS_ERR);

    if (atol(szUsrInvNum) == 0L) {
		vdDisplayMessageFromFile(INVALID_INV_NUM_ERR_MSG, STATUS_MSG);
        SVC_WAIT(2000);
        return (VS_ERR);
    }
    pobTran->srBKey.lnInvNum = atol(szUsrInvNum);

    return(VS_SUCCESS);
}

int inImamGetAuthCode(TRANSACTION_OBJECT* pobTran) 
{
    char szAuthCode[AUTH_CODE_SIZE + 1];
    char szDisplayBuffer[DISP_STR_LEN + 1];
    int inResult,
    inTemp;

	if ((pobTran->srTRTRec.TransactionCode==REFUND || pobTran->srTRTRec.TransactionCode==REFUND_DEBIT) && 
		(!fGetImamRefundApprCode())) {
		return (VS_SUCCESS);
	}
/*
	if (pobTran->srBRec.inTranCardType == DEBIT_CARD){
	} else {
		return (VS_SUCCESS);
	}
*/
    if (getgrid() == 0)
        inResult = inCPACEnterWithMessage(AUTH_CODE_MSG, SCROLL_DISPLAY_FALSE, 3, 6, szAuthCode, INPUT_ALNUMS, AUTH_CODE_SIZE, inCITIValidateString);
    else
        inResult = inCPACEnterWithMessage(AUTH_CODE_MSG, SCROLL_DISPLAY_TRUE, inImamLineNumber-1, inImamLineNumber-1, szAuthCode, INPUT_ALNUMS, AUTH_CODE_SIZE, inCITIValidateString);

    if (inResult >= 0) {
        strcpy(pobTran->srBRec.szAuthCode, szAuthCode);
        memset(szDisplayBuffer, 0, sizeof(szDisplayBuffer));
        vdGetMessageFromFile(TRANS_APP_MSG, szDisplayBuffer);
        if (getgrid() != 0) {
            strcat(szDisplayBuffer, " ");
            strcat(szDisplayBuffer, szAuthCode);
            vdDisplayAt(1, inImamLineNumber, szDisplayBuffer, CLR_EOL);
        } else {
            inTemp = strlen(szDisplayBuffer);
            szDisplayBuffer[inTemp] = 0x01;
            szDisplayBuffer[inTemp + 1] = 0x20;
            szDisplayBuffer[inTemp + 1 + 1] = 0x00;
            vdDisplayAt(1, 4, szDisplayBuffer, CLR_EOL);
            vdDisplayDataStr(szAuthCode, 8, NO_CLEAR, ML_RIGHT);
            vdSGRespMsg(szDisplayBuffer);
        }
        inResult = VS_SUCCESS;
    }   
    return(inResult);
}

void vdImamEntryDisplayAt(WIN_INFO* wi8x21Win,int inCol,int inRow,char* szDispBuf,int inClear) {
    int inLeft,
    inTop,
    inRight,
    inBottom;
    char szFontName[FILENAME_SIZE + 1];

    if (obDisp.blActionFontASC8x21)
        vdDisplayAt(inCol, inRow, szDispBuf, inClear);
    else {
        wherewin(&inLeft, &inTop, &inRight, &inBottom);
        get_font(szFontName);
        set_font(ASC8X21_VFT);
        window(wi8x21Win->inLeft, wi8x21Win->inTop, wi8x21Win->inRight, wi8x21Win->inBottom);
        vdDisplayAt(inCol, inRow, szDispBuf, inClear);
        set_font(szFontName);

        window(inLeft, inTop, inRight, inBottom);
    }
    return;
}        


int inImamWaitKey(int inSeconds) {
    unsigned long ulTimerCount;
    int inTimeout = 0;
    long lnEvent = 0;
    int inTimer = 0;

    if (KBHIT()) return(get_char());

	if (inGetUCLCommLink()) {
	    ulTimerCount = set_itimeout(NO_CLOCK_HANDLE inSeconds, TM_SECONDS);
	   
    	while (CHECK_TIMEOUT(ulTimerCount) != 0) {
			inBackGroundWirelessControl(0, MODEM_PPP_CONNECTED);
			if (KBHIT()) return(get_char());
			SVC_WAIT(0);
	    }

	} else {
		do {
			/* Set the required timeout before we start */
			inTimer = set_timer((long)inSeconds * 1000, EVT_TIMER);

			/* THIS IS IF SOFTPAY IS THE ONLY APPLICATION !!!!! */
			lnEvent = 0;
			while (((lnEvent & EVT_KBD) == 0) && ((lnEvent & EVT_TIMER) == 0)){
				/* THIS IS IF SOFTPAY IS THE ONLY APPLICATION !!!!! */
				lnEvent = wait_event();
			}

			/* Clear any existing timer */
			clr_timer(inTimer);

			if (lnEvent & EVT_KBD) {
        		return(get_char());
			} else {
				break;
			}
/*
			// KV1 20010105 - Allow terminal to go to sleep
    		if ( srGDS.fHandHeld && srGDS.fBatteryOperated && get_dock_status () == HANDHELD_UNDOCKED ){
    			vdTerminalSleep ();
			} else {
				break;
			}
*/
		} while (VS_TRUE);
	}
    //NKJT gu_clr_state = TRUE;
    return(KEY_CANCEL);
}


int inImamRecvCModePacket(int inHandle,char* pchRecBuf,int inMaxRecSize,VS_BOOL fStripStxEtx,int inRespTimeOut,VS_BOOL fSendAck,int inMaxRetries) {
    VS_BOOL fLRC;
    VS_BOOL fEnd = VS_FALSE;
    VS_BOOL fTimedOut = VS_FALSE;
    char chCheckSO = (char) - 1;  /* Default = uninitialized */
    char chAckOrNak;
    char szRecBuf[RECV_BUF_SIZE + 1];
    int inLRC;
    int inNumRetry = 0;
    int inSize;
	unsigned long ulTimerCount;

    do {
        inSize = 0;
        fEnd = VS_FALSE;

        memset(szRecBuf, 0x00, (int)sizeof(szRecBuf));

        inNumRetry++;

        if (inRespTimeOut)    /* If a timeout was passed */
            ulTimerCount = set_itimeout(NO_CLOCK_HANDLE inRespTimeOut, TM_SECONDS);

        while (1)                                      /* Check if Time Expired */ {
            if (inRespTimeOut)    /* If a timeout was passed */ {
                if (CHECK_TIMEOUT(ulTimerCount) == 0) {
                    fTimedOut = VS_TRUE;
                    break;  /* Timeout occurred */
                }
            }

			inBackGroundWirelessControl(0, MODEM_PPP_CONNECTED);

            /* Read one char at a time till we get ETX or SO or EOT */
            if (read(inHandle, szRecBuf + inSize, 1) > 0) {
                inSize++;

                /* Check that we have to exceeded the actual buffer space availalble */
                if (inSize >= sizeof(szRecBuf))
                    return VS_ERROR;

                if (chCheckSO == (char) - 1) {
                    if (szRecBuf[0] == STX)
                        chCheckSO = VS_FALSE;
                    else
                        chCheckSO = VS_TRUE;
                }

                if (fEnd == VS_TRUE)
                    break;

                if ((szRecBuf[inSize - 1] == ETX) && (chCheckSO == VS_FALSE))
                    fEnd = VS_TRUE; /* Break out only after reading LRC */
                else if ((szRecBuf[inSize - 1] == SO) && (chCheckSO == VS_TRUE))
                    fEnd = VS_TRUE;
                else if (szRecBuf[inSize - 1] == EOT)
                    return(VS_ESCAPE);
            }

            if (gu_clr_state())     /* CANCEL key pressed */
                return(VS_ESCAPE);
        } 

        if (inSize == 0 || inSize == 1) {
            // Can't check LRC if only one byte so error out
            fTimedOut = VS_TRUE;
            break;                  /* No response from device - timed out */
        }

        if (szRecBuf[0] == EOT)
            break;                  /* EOT received....break! */

        inLRC = SVC_CRC_CALC(0, &(szRecBuf[1]), inSize - 2);

        /* Should check LRC and set OK */
        fLRC = (char) (szRecBuf[inSize - 1] == inLRC);

        if (szRecBuf[inSize - 1] == 0x00)    /* If LRC == NULL_CH, change so string */
            szRecBuf[inSize - 1] = 0x01;     /* ops will function correctly later */
        szRecBuf[inSize] = 0x00;           /* NULL_CH the packet */

        /* Send ACK or NAK depending on device Response */
        if (fSendAck) {
            chAckOrNak = (char) (fLRC ? ACK : NAK);
            write(inHandle, &chAckOrNak, 1);
        }
    } while ((!fLRC) && (inNumRetry < inMaxRetries));

    if (fTimedOut)
        return (ERR_COM_TIMEOUT);

    /* Strip off STX/ETX if required */
    if (fStripStxEtx) {
        memcpy((char *) szRecBuf, (char *) szRecBuf + 1, (inSize - 3));
        szRecBuf[inSize - 3] = 0;
        inSize -= 3;
    }

    /* Copy to application buffer */
    strncpy(pchRecBuf, szRecBuf, inMaxRecSize);                 

    /* Return smaller of two */
    inSize = (inSize < inMaxRecSize) ? inSize : inMaxRecSize;

    return(inSize);
}

int inImamSettleAllHost(TRANSACTION_OBJECT *pobTran)
{
    int inHostIndex;
	int inHosts=MAX_HOSTS;
	int inRetval = VS_SUCCESS;

	for (inHostIndex = 0; inHostIndex < inHosts; inHostIndex++) {
		if (inGetMerchantNum() == 0)
            inLoadMITRec(0);

        if (inLoadDefaultHost (inHostIndex) != VS_SUCCESS)
            return (VS_ERR);

        if (inLoadDefaultCurrency (pobTran) != VS_SUCCESS)
            return (VS_ERR);
        vdSetHostHandle(inHostIndex);
	    inImamDownloadHostLogo(pobTran);
		if (inRetval == VS_SUCCESS) inRetval = inCPACGetMerchEnable(pobTran);
		if (inRetval == VS_SUCCESS) inRetval = inCPACSettleOperation (pobTran);
		if (inRetval != VS_SUCCESS) break;
    }
	return inRetval;
}

int inImamEchoAllHost(TRANSACTION_OBJECT *pobTran)
{
    int inHostIndex;
	int inHosts=MAX_HOSTS;
	int inRetval = VS_SUCCESS;

		LOG_PRINTFF((0x08L, "inImamEchoAllHost 1 "));

	for (inHostIndex = 0; inHostIndex < inHosts; inHostIndex++) {
		if (inGetMerchantNum() == 0)
            inLoadMITRec(0);
LOG_PRINTFF((0x08L, "inImamEchoAllHost 2 "));
        if (inLoadDefaultHost (inHostIndex) != VS_SUCCESS)
            return (VS_ERR);
LOG_PRINTFF((0x08L, "inImamEchoAllHost 3 "));
        if (inLoadDefaultCurrency (pobTran) != VS_SUCCESS)
            return (VS_ERR);
		LOG_PRINTFF((0x08L, "inImamEchoAllHost 4 "));
        vdSetHostHandle(inHostIndex);
	    
		if (inRetval == VS_SUCCESS) inRetval = inCPACGetMerchEnable(pobTran);
		if (inRetval == VS_SUCCESS) inRetval = inImamEchoOneHost (pobTran);
		if (inRetval != VS_SUCCESS) break;
    }
	pause(500);
	return inRetval;
}

int inImamResetLogonStatus(TRANSACTION_OBJECT *pobTran)
{
    int inHostIndex;
	int inHosts=MAX_HOSTS;
	int inRetval = VS_SUCCESS;

	for (inHostIndex = 0; inHostIndex < inHosts; inHostIndex++) {
		LOG_PRINTFF((0x08, "RESET LOGON STATUS HOST = [%d]", inHostIndex));
		inRetval = inLoadHDTRec(inHostIndex);
		if (inRetval != VS_SUCCESS) break;

		if (fGetImamNeedLogon()) {
			vdSetImamLogonStatus(0);
		} else {
			vdSetImamLogonStatus(1);
		}
		inSaveHDTRec(inHostIndex);
    }
	return inRetval;
}

int inImamLogonAllHost(TRANSACTION_OBJECT *pobTran)
{
    int inHostIndex;
	int inHosts=MAX_HOSTS;
	int inRetval = VS_SUCCESS;

	for (inHostIndex = 0; inHostIndex < inHosts; inHostIndex++) {
		if (inGetMerchantNum() == 0)
            inLoadMITRec(0);

        if (inLoadDefaultHost (inHostIndex) != VS_SUCCESS)
            return (VS_ERR);

        if (inLoadDefaultCurrency (pobTran) != VS_SUCCESS)
            return (VS_ERR);
        vdSetHostHandle(inHostIndex);
	    
		if (inRetval == VS_SUCCESS) inRetval = inCPACGetMerchEnable(pobTran);
		if (inRetval == VS_SUCCESS) inRetval = inImamLogonOneHost (pobTran);
		if (inRetval != VS_SUCCESS) break;
    }
	pause(500);
	return inRetval;
}

int inImamEchoOneHost(TRANSACTION_OBJECT *pobTran)
{
	int inRetval = VS_SUCCESS;
    short inMyTranCode;
    short inPIPTransCode;
	char buff[128];
    PACKET_OBJECT obPacket;
		
	memset(buff, 0x00, sizeof(0x00));
	sprintf(buff, "[%s].......................", szGetHostName());
	buff[19]=0x00;
	DisplayStatus(buff);
	vdScrollDisplay();
	if (!fGetImamEchoTest()) {
		strcpy(&buff[17], "SKIP");
		vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
		return (VS_SUCCESS);
	}
    if (fGetDemoMode() == VS_TRUE) {
		strcpy(&buff[19], "OK");
		vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
        return (VS_SUCCESS);
    }

//obCommunication.inInitialize();

    if (obCommunication.inBegin) {
        if (obCommunication.inBegin(&obCommunication, shGetCommunicationIndex(), VS_TRUE) != VS_SUCCESS){
		    strcpy(&buff[17], "FAIL");
		    vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
            return (VS_SUCCESS);
        }
	}

    if (obCommunication.inCheck) {
        if (obCommunication.inCheck(&obCommunication) != VS_SUCCESS) {
		    strcpy(&buff[17], "FAIL");
		    vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
            return (VS_SUCCESS);
        }
	}



    if ((psrHostData = psrCreateHostData()) == (HOST_8583_DATA *) NULL_CH) {
        vdFreeHostData(psrHostData);
        vdFreeVariantTables();
        vdSGErrorMessage(NO_MEM_ERR_MSG);
		strcpy(&buff[17], "FAIL");
		vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
        return (VS_SUCCESS);
    }

	inIncSTAN();
    pobTran->srBRec.lnSTAN = lnGetSTAN();


    if (inInitializePacket(&obPacket) != VS_SUCCESS) {
		strcpy(&buff[17], "FAIL");
		vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
        return (VS_SUCCESS);
    }
    if (obPacket.inInitialize(&obPacket) != VS_SUCCESS) {
		strcpy(&buff[17], "FAIL");
		vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
        return (VS_SUCCESS);
    }


    if ((psrHostData->c8583_data = psrCreateCommData(pobTran, CPAC_SEND_SIZE, VS_FALSE /*VS_TRUE*/)) == (COMM_8583_DATA *) NULL_CH) {
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        vdFreeISO8583Data(psrHostData);
		strcpy(&buff[17], "FAIL");
		vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
        return (VS_SUCCESS);
    }


	psrHostData->c8583_data->transceiver = inImamTxRx8583;  //
#ifdef MODEM
	if (inGetUCLCommLink()==0) {  // to get resp timeout
		MODEM_OBJECT *obModem;
		obModem = (MODEM_OBJECT *)obCommunication.Data;
		psrHostData->c8583_data->comm_timeout         = obModem->shGetRespTimeOut(obModem->srCPT);  // for Response TimeOut
		psrHostData->c8583_data->wait_for_carrier     = obModem->shGetCarrierTimeOut(obModem->srCPT); // for Carier TimeOut
	}
#endif

    ((VALIDATION_STRUCT *) (psrHostData->c8583_data->v_parms))->comm_struct = psrHostData->c8583_data;
	psrHostData->c8583_data->validation = (PFI_PVOID_INT) inCPACBaseRespValidation; 
	psrHostData->reverse_flag = VS_FALSE; // Disable reversal ?

	obPacket.inError = 0;			
    pobTran->srBRec.inCode = IMAM_ECHO; //vdSGCode(IMAM_ECHO);     
	pobTran->inTransactionCode = IMAM_ECHO;
	pobTran->srTRTRec.TransactionCode = IMAM_ECHO;

	//inMyTranCode = shVerifyCPACTransType(pobTran);  
    inMyTranCode = IMAM_ECHO;
    inStoreTranFlexiData(pobTran, AMEX_PIP_TRANS_CODE, (unsigned char *) &inMyTranCode, 2);

	LOG_PRINTFF((0x08L, "AFTER STORE TRAN"));
	
    if ((inPIPTransCode = shLoadPIPTransCode(inMyTranCode)) == VS_ERR) {
        vdFreeISO8583Data(psrHostData);
		strcpy(&buff[17], "FAIL");
		vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
        return (VS_SUCCESS);
    }

	vdDispMsgAt(WAIT_MSG, 1, inImamLineNumber, CLR_EOL);
	errno = 0;

	LOG_PRINTFF((0x08L, "BEFORE PIP_TRAN"));
	strcpy((char *) srISO.pszField39, "00");
	inRetval = pip_trans(inPIPTransCode, psrHostData);
    if (inRetval != PIP_APPROVAL) {
		strcpy(&buff[17], "FAIL");
		LOG_PRINTFF((0x08L, "ECHO GAGAL : NOT PIP_APPROVAL [%d]", inRetval));
	} else if ((inRetval == PIP_APPROVAL) && (!strncmp((char *) srISO.pszField39, "00", 2))) {
		strcpy(&buff[19], "OK");
		LOG_PRINTFF((0x08L, "ECHO OK : PIP_APPROVAL [%d]", inRetval));
    } else {
		strcpy(&buff[17], "FAIL");
        LOG_PRINTFF((0x08L, "ECHO GAGAL : RESPONSE CODE [%s]", (char *) srISO.pszField39));
    }
	vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
    vdFreeISO8583Data(psrHostData);
    if (obCommunication.inEnd) obCommunication.inEnd(&obCommunication);
	return VS_SUCCESS;
}

int inImamLogonOneHost(TRANSACTION_OBJECT *pobTran)
{
	int inRetval = VS_SUCCESS;
    short inMyTranCode;
    short inPIPTransCode;
	char buff[128];
    PACKET_OBJECT obPacket;
	unsigned char buffKey[40];
	#ifndef IMAM_BNI
	unsigned char buff2[40];
	int keyLength;
	
	#endif
	unsigned char buff3[40];
	
	int len63=0;
	int a=0;

	memset(buff, 0x00, sizeof(buff));
	memset(buff3, 0x00, sizeof(buff3));
	sprintf(buff, "[%s].......................", szGetHostName());
	buff[19]=0x00;
	DisplayStatus(buff);
	vdScrollDisplay();
	if ((!fGetImamNeedLogon()) || 
	    ((fGetImamNeedLogon()) && (fGetImamLogonStatus()))) {
		strcpy(&buff[17], "SKIP");
		vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
		return (VS_SUCCESS);
	}
    if (fGetDemoMode() == VS_TRUE) {
		strcpy(&buff[19], "OK");
		vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
        return (VS_SUCCESS);
    }

    if (obCommunication.inBegin) {
        if (obCommunication.inBegin(&obCommunication, shGetCommunicationIndex(), VS_TRUE) != VS_SUCCESS){
		    strcpy(&buff[17], "FAIL");
		    vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
            return (VS_SUCCESS);
        }
	}
    if (obCommunication.inCheck) {
        if (obCommunication.inCheck(&obCommunication) != VS_SUCCESS) {
		    strcpy(&buff[17], "FAIL");
		    vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
            return (VS_SUCCESS);
        }
	}

    if ((psrHostData = psrCreateHostData()) == (HOST_8583_DATA *) NULL_CH) {
        vdFreeHostData(psrHostData);
        vdFreeVariantTables();
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        return (VS_ERR);
    }

	inIncSTAN();
    pobTran->srBRec.lnSTAN = lnGetSTAN();

    if (inInitializePacket(&obPacket) != VS_SUCCESS) {
        return(VS_ERR);
    }
    if (obPacket.inInitialize(&obPacket) != VS_SUCCESS) {
        return(VS_ERR);
    }

    if ((psrHostData->c8583_data = psrCreateCommData(pobTran, CPAC_SEND_SIZE, VS_FALSE /*VS_TRUE*/)) == (COMM_8583_DATA *) NULL_CH) {
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        vdFreeISO8583Data(psrHostData);
        return (VS_ERR);
    }

	psrHostData->c8583_data->transceiver = inImamTxRx8583;  //
#ifdef MODEM
	if (inGetUCLCommLink()==0) {  // to get resp timeout
		MODEM_OBJECT *obModem;
		obModem = (MODEM_OBJECT *)obCommunication.Data;
		psrHostData->c8583_data->comm_timeout         = obModem->shGetRespTimeOut(obModem->srCPT);  // for Response TimeOut
		psrHostData->c8583_data->wait_for_carrier     = obModem->shGetCarrierTimeOut(obModem->srCPT); // for Carier TimeOut
	}
#endif

    ((VALIDATION_STRUCT *) (psrHostData->c8583_data->v_parms))->comm_struct = psrHostData->c8583_data;
	psrHostData->c8583_data->validation = (PFI_PVOID_INT) inCPACBaseRespValidation; 
	psrHostData->reverse_flag = VS_FALSE; // Disable reversal ?

	obPacket.inError = 0;			
    pobTran->srBRec.inCode = IMAM_LOGON; //vdSGCode(IMAM_ECHO);     
	pobTran->inTransactionCode = IMAM_LOGON;
	pobTran->srTRTRec.TransactionCode = IMAM_LOGON;


	//inMyTranCode = shVerifyCPACTransType(pobTran);  
    inMyTranCode = IMAM_LOGON;
    inStoreTranFlexiData(pobTran, AMEX_PIP_TRANS_CODE, (unsigned char *) &inMyTranCode, 2);

	LOG_PRINTFF((0x08L, "AFTER STORE TRAN"));
	
    if ((inPIPTransCode = shLoadPIPTransCode(inMyTranCode)) == VS_ERR) {
        vdFreeISO8583Data(psrHostData);
        return (VS_ERR);
    }
	LOG_PRINTFF((0x08L, "inPIPTransCode = [%d]", inPIPTransCode));

	vdDispMsgAt(WAIT_MSG, 1, inImamLineNumber, CLR_EOL);
	errno = 0;
	LOG_PRINTFF((0x08L, "BEFORE PIP_TRAN"));

	inRetval = pip_trans(inPIPTransCode, psrHostData);
    if (inRetval != PIP_APPROVAL) {
		strcpy(&buff[17], "FAIL");
		LOG_PRINTFF((0x08L, "LOGON GAGAL : NOT PIP_APPROVAL [%d]", inRetval));
	} else if ((inRetval == PIP_APPROVAL) && (!strncmp((char *) srISO.pszField39, "00", 2))) {
		strcpy(&buff[19], "OK");
		LOG_PRINTFF((0x08L, "LOGON HOST [%d][%d] OK : PIP_APPROVAL [%d]", inGetHostIndex(), inGetHostHandle(), inRetval));
		vdSetImamLogonStatus(1);
		inSaveHostData(inGetHostHandle());
		//edi - save working key
		memset(buffKey,0x00,sizeof(buffKey));
		memset(buff,0x00,sizeof(buff));

		strncpy((char *)buffKey,(char *)&srISO.pszField63[4],16);
		SVC_HEX_2_DSP((char *)buffKey,buff,16);
		put_env_x("TD.WKEY", 0, buff);
		put_env_x("#CZE", 0, "1");

/*
		a = strcspn((char *)srISO.pszField63,"KP");
		if(a>0){
			strncpy(buffKey,(char *)&srISO.pszField63[a+1],16);
			SVC_HEX_2_DSP(buffKey,buff,16);
			put_env_x("TD.WKEY", 0, buff);
			put_env_x("#CZE", 0, "1");
		}
*/
/*		
		memset(buff2,0x00,sizeof(buff2));
		memset(buff3,0x00,sizeof(buff3));
		strncpy(buff2,buff,21);
		strncpy(buff3,&buff[21],11);
		DisplayStatus(buff2);
		SVC_WAIT(3000);
		DisplayStatus(buff3);
		SVC_WAIT(3000);
*/		
		LOG_PRINTFF((0x08L,"index Working Key -> %i \n",a));
		LOG_PRINTFF((0x08L,"Working Key -> %s \n",buff));
		
/*
		keyLength = 32;
		memset(buffKey,0x00,sizeof(buffKey));
		memset(buff,0x00,sizeof(buff));
		//strncpy(buffKey,(char *)srISO.pszField62,keyLength);
		strncpy(buffKey,(char *)&srISO.pszField63[34],16);
		if(keyLength == 16){ //des
			SVC_HEX_2_DSP(buffKey,buff,8);
			inLoadDCTRec(inGetHostHandle());
			vdSetPINKey(buff);
			inSaveDCTRec(inGetHostHandle());
		}else if(keyLength == 32){//triple des
			SVC_HEX_2_DSP(buffKey,buff,16);
			put_env_x("TD.WKEY", 0, buff);
			put_env_x("#CZE", 0, "1");
		}
*/	
		/**************************************************/

    } else {
		strcpy(&buff[17], "FAIL");
        LOG_PRINTFF((0x08L, "LOGON GAGAL : RESPONSE CODE [%s]", (char *) srISO.pszField39));
    }
	vdDisplayAt(1, inImamLineNumber-1, buff, CLR_EOL);
    vdFreeISO8583Data(psrHostData);
    if (obCommunication.inEnd) obCommunication.inEnd(&obCommunication);
	inRetval= VS_SUCCESS;
	return inRetval;
}

int inImamLogonOneHostOnDemand(TRANSACTION_OBJECT *pobTran)
{
	int inRetval = VS_SUCCESS;
    short inMyTranCode;
    short inPIPTransCode;
	char buff[128];
    PACKET_OBJECT obPacket;
	short inCode = pobTran->srBRec.inCode;
	short inTransactionCode = pobTran->inTransactionCode;
	short TransactionCode = pobTran->srTRTRec.TransactionCode;
	unsigned char buffKey[40];
	
	if (fGetOffline(pobTran)) return VS_SUCCESS;
	
	memset(buff, 0x00, sizeof(0x00));
	sprintf(buff, "Logon [%s]...", szGetHostName());
	DisplayStatus(buff);
	if ((!fGetImamNeedLogon()) || 
	    ((fGetImamNeedLogon()) && (fGetImamLogonStatus()))) {
		strcpy(&buff[17], "SKIP");
		DisplayStatus(buff);
		return (VS_SUCCESS);
	}
    if (fGetDemoMode() == VS_TRUE) {
		strcpy(&buff[19], "OK");
		DisplayStatus(buff);
        return (VS_SUCCESS);
    }

    if (obCommunication.inCheck) {
        if (obCommunication.inCheck(&obCommunication) != VS_SUCCESS) {
            return(VS_ERR);
        }
	}
	DisplayStatus(buff);

    if ((psrHostData = psrCreateHostData()) == (HOST_8583_DATA *) NULL_CH) {
        vdFreeHostData(psrHostData);
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        return (VS_ERR);
    }

	inIncSTAN();
    pobTran->srBRec.lnSTAN = lnGetSTAN();

    if (inInitializePacket(&obPacket) != VS_SUCCESS) {
        return(VS_ERR);
    }

    if (obPacket.inInitialize(&obPacket) != VS_SUCCESS) {
        return(VS_ERR);
    }

    if ((psrHostData->c8583_data = psrCreateCommData(pobTran, CPAC_SEND_SIZE, VS_FALSE /*VS_TRUE*/)) == (COMM_8583_DATA *) NULL_CH) {
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        vdFreeISO8583Data(psrHostData);
        return (VS_ERR);
    }

	psrHostData->c8583_data->transceiver = inImamTxRx8583;  //
#ifdef MODEM
	if (inGetUCLCommLink()==0) {  // to get resp timeout
		MODEM_OBJECT *obModem;
		obModem = (MODEM_OBJECT *)obCommunication.Data;
		psrHostData->c8583_data->comm_timeout         = obModem->shGetRespTimeOut(obModem->srCPT);  // for Response TimeOut
		psrHostData->c8583_data->wait_for_carrier     = obModem->shGetCarrierTimeOut(obModem->srCPT); // for Carier TimeOut
	}
#endif

    ((VALIDATION_STRUCT *) (psrHostData->c8583_data->v_parms))->comm_struct = psrHostData->c8583_data;
	psrHostData->c8583_data->validation = (PFI_PVOID_INT) inCPACBaseRespValidation; 
	psrHostData->reverse_flag = VS_FALSE; // Disable reversal ?

	obPacket.inError = 0;			
    pobTran->srBRec.inCode = IMAM_LOGON; //vdSGCode(IMAM_ECHO);     
	pobTran->inTransactionCode = IMAM_LOGON;
	pobTran->srTRTRec.TransactionCode = IMAM_LOGON;

	//inMyTranCode = shVerifyCPACTransType(pobTran);  
    inMyTranCode = IMAM_LOGON;
    inStoreTranFlexiData(pobTran, AMEX_PIP_TRANS_CODE, (unsigned char *) &inMyTranCode, 2);

	LOG_PRINTFF((0x08L, "AFTER STORE TRAN"));
	
    if ((inPIPTransCode = shLoadPIPTransCode(inMyTranCode)) == VS_ERR) {
        vdFreeISO8583Data(psrHostData);
		pobTran->srBRec.inCode = inCode;
		pobTran->inTransactionCode = inTransactionCode;
		pobTran->srTRTRec.TransactionCode = TransactionCode;
        return (VS_ERR);
    }

	vdDispMsgAt(WAIT_MSG, 1, inImamLineNumber, CLR_EOL);
	errno = 0;

	LOG_PRINTFF((0x08L, "BEFORE PIP_TRAN"));

	inRetval = pip_trans(inPIPTransCode, psrHostData);    
	vdFreeISO8583Data(psrHostData);

    if (inRetval != PIP_APPROVAL) {
		strcpy(&buff[17], "FAIL");
		LOG_PRINTFF((0x08L, "LOGON GAGAL : NOT PIP_APPROVAL [%d]", inRetval));
		DisplayStatus(buff);
		SVC_WAIT(2000);
		return VS_ERR;
	} else if ((inRetval == PIP_APPROVAL) && (!strncmp((char *) srISO.pszField39, "00", 2))) {
		strcpy(&buff[19], "OK");
		LOG_PRINTFF((0x08L, "LOGON HOST [%d] OK : PIP_APPROVAL [%d]", inGetHostIndex(), inRetval));
		vdSetImamLogonStatus(1);
		inSaveHostData(inGetHostHandle());

		//edi - save working key
/*		
		memset(buffKey,0x00,sizeof(buffKey));
		memset(buff,0x00,sizeof(buff));
		strncpy(buffKey,(char *)&srISO.pszField63[4],16);
		SVC_HEX_2_DSP(buffKey,buff,16);
		put_env_x("TD.WKEY", 0, buff);
		put_env_x("#CZE", 0, "1");
*/
		/*edi add to save working key in isomessagefield62 to table
		if(strlen((char *) srISO.pszField62)<=16){
			inLoadDCTRec(inGetHostHandle());
			vdSetPINKey((char *) srISO.pszField62);
			inSaveDCTRec(inGetHostHandle());
		}else{
			memset(buff,0x00,sizeof(buff));
			//SVC_HEX_2_DSP( (char *) srISO.pszField62,buff,strlen((char *) srISO.pszField62)/2);
			put_env_x("TD.WKEY", 0, (char *) srISO.pszField62);
			
		}*/
		/**************************************************/
    } else {
		strcpy(&buff[17], "FAIL");
        LOG_PRINTFF((0x08L, "LOGON GAGAL : RESPONSE CODE [%s]", (char *) srISO.pszField39));
		DisplayStatus(buff);
		SVC_WAIT(2000);
		return VS_ERR;
    }
	{//return it to original one 
		pobTran->srBRec.inCode = inCode;
		pobTran->inTransactionCode = inTransactionCode;
		pobTran->srTRTRec.TransactionCode = TransactionCode;
	}
	return VS_SUCCESS;
}

int inImamComputeMac(unsigned char *szData, int inDataSize)
{
	int inRetval;
	char szPacketZ66[1024];  //maximum is 244-256?
	char szPacketZ67[1024];
	int  inPacketZ66Size = 0;
	char szASCData[1024]; 
	int  inASCDataBlockNum_224 = 0;
	int  inASCDataBlockNum_8 = 0;
	char szMacWK[33];
	int i = 0;

	inResetPINPad();
	if (obPinPad.inPPadConnectTest() != VS_SUCCESS) {
	   LOG_PRINTFF((0x08L, "PINPAD TEST CONNECT ERROR"));
       vdSGErrorMessage(PINPAD_ERR_MSG21);
       INCREMENT_PINPAD_ERROR;
	   gfPPadPresent = VS_FALSE;
       return(VS_ERR);
    }
	{
		int inMacDataSize = inDataSize - 13; //TPDU + F64
		memset(szASCData, 0x00, sizeof(szASCData));
		SVC_HEX_2_DSP((char *)&szData[5], szASCData, inMacDataSize); //start after TPDU
		//strcpy(szASCData, "08102038010002C008059200000000071139320408009030304930393330303030363039303336303137393930303031000000000000000000853434343731313732343434373131373242495A4E45542034544820464C4F4F52202020202020204A414B41525441202020202020202020202020202020204D45524348414E542044454D4F20202020202020202020");
		//inMacDataSize = strlen(szASCData)/2;

		inASCDataBlockNum_224 = (inMacDataSize*2) / 224;         //224 is max allowed as mentioned in DOC
		if ((inMacDataSize*2)%224) inASCDataBlockNum_224++;		
		
		//inASCDataBlockNum_8 = (inMacDataSize*2) / 8;
		//if ((inMacDataSize*2)%8) inASCDataBlockNum_8++;
		//strncat(szASCData, "00000000", inASCDataBlockNum_8*8 - (inMacDataSize*2));  //add '0' filler
	}
	
	{
		memset(szMacWK, 0x00, sizeof(szMacWK));
		strcpy(szMacWK, szGetPINKey());
		//strcpy(szMacWK, "3434343731313732");  //Test only
		LOG_PRINTFF((0x08L, "MAC WK = [%s]", szMacWK));
	}

	for (i=0; i<inASCDataBlockNum_224; i++ ) { //compose packet Z66 Request MAC
		memset(szPacketZ66, 0x00, sizeof(szPacketZ66));
		//szPacketZ66[0] = 0x02;  //will be add auto
		strcat(szPacketZ66, "Z66");
		if (i == inASCDataBlockNum_224 - 1) {
			strcat(szPacketZ66, "6");		//Last Ascii Packet. as in this case only one packet
		} else {
			strcat(szPacketZ66, "7");		//First Ascii Packet. as in this case only one packet
		}
		{
			char buff[4];
			memset(buff, 0x00, sizeof(buff));
			sprintf(buff, "%02d", i);
			strcat(szPacketZ66, buff);		//Packet Sequence
		}
		szPacketZ66[strlen(szPacketZ66)] = chGetMasterKeyAddress();		//MasterKey Pointer, same key as PIN MK
		//szPacketZ66[strlen(szPacketZ66)] = '0';
		szPacketZ66[strlen(szPacketZ66)] = 0x1C;						//Field Separator
		strcat(szPacketZ66, szMacWK);								    //Add Working Key
		szPacketZ66[strlen(szPacketZ66)] = 0x1C;						//Field Separator
		//szPacketZ66[strlen(szPacketZ66)] = '1';
		//szPacketZ66[strlen(szPacketZ66)] = chGetMasterKeyAddress()+1;   //Optional Second MK
		szPacketZ66[strlen(szPacketZ66)] = 0x1C;						//Field Separator
		strncat(szPacketZ66, &szASCData[i*224], 224);					//the 224 MAC data
		//szPacketZ66[strlen(szPacketZ66)] = 0x03;						//End of Text. will be add auto
		inPacketZ66Size = strlen(szPacketZ66);

		LOG_PRINTFF((0x08L, "szPacketZ66 = [%d]", inPacketZ66Size));
		LOG_PRINTFF((0x08L, "szPacketZ66 = [%s]", szPacketZ66));
		inRetval = inSendPinPadData(szPacketZ66, inGetPPTimeOut(), VS_TRUE);
		LOG_PRINTFF((0x08L, "szPacketZ66 inRetval = [%d]", inRetval));
		if (inRetval < 0) {
			return(VS_ERR);
		}
		inRetval = inRecvPinPadData(szPacketZ67, inGetPPTimeOut(), sizeof(szPacketZ67), VS_TRUE);
		LOG_PRINTFF((0x08L, "szPacketZ67 = [%d]", inRetval));
		LOG_PRINTFF((0x08L, "szPacketZ67 = [%s]", szPacketZ67));
		LOG_PRINT_HEX((unsigned char *)szPacketZ67, inRetval);
	}
	if ((inRetval == VS_ESCAPE) || (inRetval == 0) || (inRetval == VS_TIMEOUT)) {
        inResetPINPad();
		DisplayStatus("PINPAD MAC ERROR");
		SVC_WAIT(2000);
        return(PP_ERROR); 
	}
    if (szPacketZ67[0] == EOT){
		DisplayStatus("PINPAD MAC ERROR");
		SVC_WAIT(2000);
        return(PP_CANCEL);
	}

	{//Extract the MAC and copy to F64
		SVC_DSP_2_HEX((char *)&szPacketZ67[5], (char *)&szData[inDataSize-8], 8);
		//memcpy(&szData[inDataSize-8], &szPacketZ67[5], 4);
	}
	return(VS_SUCCESS);
}

int inImamValidateMac(unsigned char *szData, int inDataSize)
{
	int inRetval;
	char szPacketZ66[1024];  //maximum is 244-256?
	char szPacketZ67[1024];
	int  inPacketZ66Size = 0;
	char szASCData[1024]; 
	int  inASCDataBlockNum_224 = 0;
	int  inASCDataBlockNum_8 = 0;
	char szMacWK[33];
	int i = 0;

	inResetPINPad();
	if (obPinPad.inPPadConnectTest() != VS_SUCCESS) {
	   LOG_PRINTFF((0x08L, "PINPAD TEST CONNECT ERROR"));
       vdSGErrorMessage(PINPAD_ERR_MSG21);
       INCREMENT_PINPAD_ERROR;
	   gfPPadPresent = VS_FALSE;
       return(VS_ERR);
    }
	{
		int inMacDataSize = inDataSize - 13; //TPDU + F64
		memset(szASCData, 0x00, sizeof(szASCData));
		SVC_HEX_2_DSP((char *)&szData[5], szASCData, inMacDataSize); //start after TPDU
		//strcpy(szASCData, "08102038010002C008059200000000071139320408009030304930393330303030363039303336303137393930303031000000000000000000853434343731313732343434373131373242495A4E45542034544820464C4F4F52202020202020204A414B41525441202020202020202020202020202020204D45524348414E542044454D4F20202020202020202020");
		//inMacDataSize = strlen(szASCData)/2;

		inASCDataBlockNum_224 = (inMacDataSize*2) / 224;         //224 is max allowed as mentioned in DOC
		if ((inMacDataSize*2)%224) inASCDataBlockNum_224++;		
		
		//inASCDataBlockNum_8 = (inMacDataSize*2) / 8;
		//if ((inMacDataSize*2)%8) inASCDataBlockNum_8++;
		//strncat(szASCData, "00000000", inASCDataBlockNum_8*8 - (inMacDataSize*2));  //add '0' filler
	}
	
	{
		char buff[33];
		char szDCTndx[10];
		memset(buff, 0x00, sizeof(buff));
		memset(szDCTndx, 0x00, sizeof(szDCTndx));
		memset(szMacWK, 0x00, sizeof(szMacWK));
		if (strncmp(szASCData, "0810", 4)==0) {
			strncpy(buff, (char *)&szData[63], 8);
			LOG_PRINTFF((0x08L, "Compressed WK = [%s]", buff));
			SVC_HEX_2_DSP(buff, szMacWK, 8);
			vdSetPINKey(szMacWK);
			szDCTndx[0] = chGetMasterKeyAddress();
			inSaveDCTRec(atoi(szDCTndx));
		} else {
			strcpy(szMacWK, szGetPINKey());
		}
		//strcpy(szMacWK, "3434343731313732");  //Test only
		LOG_PRINTFF((0x08L, "MAC WK = [%s]", szMacWK));
	}

	for (i=0; i<inASCDataBlockNum_224; i++ ) { //compose packet Z66 Request MAC
		memset(szPacketZ66, 0x00, sizeof(szPacketZ66));
		//szPacketZ66[0] = 0x02;  //will be add auto
		strcat(szPacketZ66, "Z66");
		if (i == inASCDataBlockNum_224 - 1) {
			strcat(szPacketZ66, "6");		//Last Ascii Packet. as in this case only one packet
		} else {
			strcat(szPacketZ66, "7");		//First Ascii Packet. as in this case only one packet
		}
		{
			char buff[4];
			memset(buff, 0x00, sizeof(buff));
			sprintf(buff, "%02d", i);
			strcat(szPacketZ66, buff);		//Packet Sequence
		}
		szPacketZ66[strlen(szPacketZ66)] = chGetMasterKeyAddress();		//MasterKey Pointer, same key as PIN MK
		//szPacketZ66[strlen(szPacketZ66)] = '0';
		szPacketZ66[strlen(szPacketZ66)] = 0x1C;						//Field Separator
		strcat(szPacketZ66, szMacWK);								    //Add Working Key
		szPacketZ66[strlen(szPacketZ66)] = 0x1C;						//Field Separator
		//szPacketZ66[strlen(szPacketZ66)] = '1';
		//szPacketZ66[strlen(szPacketZ66)] = chGetMasterKeyAddress()+1;   //Optional Second MK
		szPacketZ66[strlen(szPacketZ66)] = 0x1C;						//Field Separator
		strncat(szPacketZ66, &szASCData[i*224], 224);					//the 224 MAC data
		//szPacketZ66[strlen(szPacketZ66)] = 0x03;						//End of Text. will be add auto
		inPacketZ66Size = strlen(szPacketZ66);

		LOG_PRINTFF((0x08L, "szPacketZ66 = [%d]", inPacketZ66Size));
		LOG_PRINTFF((0x08L, "szPacketZ66 = [%s]", szPacketZ66));
		inRetval = inSendPinPadData(szPacketZ66, inGetPPTimeOut(), VS_TRUE);
		LOG_PRINTFF((0x08L, "szPacketZ66 inRetval = [%d]", inRetval));
		if (inRetval < 0) {
			return(VS_ERR);
		}
		inRetval = inRecvPinPadData(szPacketZ67, inGetPPTimeOut(), sizeof(szPacketZ67), VS_TRUE);
		LOG_PRINTFF((0x08L, "szPacketZ67 = [%d]", inRetval));
		LOG_PRINTFF((0x08L, "szPacketZ67 = [%s]", szPacketZ67));
		LOG_PRINT_HEX((unsigned char *)szPacketZ67, inRetval);
	}
	if ((inRetval == VS_ESCAPE) || (inRetval == 0) || (inRetval == VS_TIMEOUT)) {
        inResetPINPad();
		DisplayStatus("PINPAD MAC ERROR");
		SVC_WAIT(2000);
        return(PP_ERROR); 
	}
    if (szPacketZ67[0] == EOT){
		DisplayStatus("PINPAD MAC ERROR");
		SVC_WAIT(2000);
        return(PP_CANCEL);
	}
	{
		char buff[17];
		memset(buff, 0x00, sizeof(buff));
		SVC_DSP_2_HEX(&szPacketZ67[5], buff, 8);
		if(memcmp(&szData[inDataSize-8], buff, 4)){//Compare the MAC...
			DisplayStatus("MAC ERROR FROM HOST");
			SVC_WAIT(2000);
			return VS_ERR;
		}
	}
	return(VS_SUCCESS);
}

int inImamSwipeCardVerify(TRANSACTION_OBJECT *pobTran)
{
	short	shRetVal = 0 ;
    char	szRawCardData[CARD_SIZE] ;
	struct	TRACK stParsedCardData ;
	char    szCardHolder[50];
	char    szPAN[50];
	char    szExpDate[10];
	char    szTrack2Data[50];
	char    buff[50];
	int retval=VS_SUCCESS;

	memset(szCardHolder, 0x00, sizeof(szCardHolder));
	memset(szPAN, 0x00, sizeof(szPAN));
	memset(szExpDate, 0x00, sizeof(szExpDate));
	memset(szTrack2Data, 0x00, sizeof(szTrack2Data));
	LOG_PRINTFF((0x08L, "SAVED PAN = [%s]", pobTran->srBRec.szPAN))
	if (pobTran->srBRec.inTranCardType != DEBIT_CARD){
		return (VS_SUCCESS);
	}
	if (fGetImamVoidSwipePin()==0){
		return (VS_SUCCESS);
	}
	if (inRunFunction(pobTran, COLD_INIT_PINPAD) != VS_SUCCESS) return (VS_ERR);
	if (inRunFunction(pobTran, GET_PIN_ACC_MAC)  != VS_SUCCESS) return (VS_ERR);
	do{
		ClearSevenLine();
		vdDisplayAt(4, inImamLineNumber/4, "  VERIFY CARD  ", CLR_EOL);
		vdDisplayAt(4, inImamLineNumber/2+1, "SWIPE YOUR CARD", CLR_EOL);
		inImamTimeOut(15000L);
		do {
			if (card_pending()==1) {
				break;
			}
			if (KBHIT()){
				if (get_char() == 27) {
					return (VS_ESCAPE);
				}
			}
			if (inImamTimeOut(0L)) return (VS_ESCAPE);
			SVC_WAIT(0);
		}while (1);
		shRetVal = read(hCardReader, szRawCardData, sizeof(szRawCardData)) ;
		if(shRetVal < 0){
			DisplayStatus("SWIPE ERR. TRY AGAIN");
			vdWarnBeep();
			SVC_WAIT(2000);
			continue;
		}
		shRetVal = card_parse(szRawCardData, &stParsedCardData, "1") ;
		if (shRetVal == 1) {
			strcpy(szCardHolder, stParsedCardData.name);
			vdTrimSpaces(szCardHolder);
			szCardHolder[21] = 0x00;
		}
		shRetVal = card_parse(szRawCardData, &stParsedCardData, "2") ;
		if(shRetVal != 2){
			DisplayStatus("SWIPE ERR. TRY AGAIN");
			vdWarnBeep();
  			SVC_WAIT(2000);
			continue;
		}	

		strcpy(szPAN, stParsedCardData.acct);
		strcpy(szExpDate, stParsedCardData.exp);		
		strcpy(szTrack2Data, stParsedCardData.track);
		ClearSevenLine();
		if (strlen(szCardHolder)>1) vdDisplayAt((22 - (strlen (szCardHolder))), inImamLineNumber-4, szCardHolder, CLR_EOL); 

		vdDisplayAt(1, inImamLineNumber-3, "PAN:", CLR_EOL);
		if (strlen (szPAN) > 17) inImamCustScroll(pobTran); 
		if (strlen (szPAN) > 21) {
			strcpy(szPAN, &szPAN[strlen(szPAN)-21]); 
			szPAN[21] = 0x00;
		}
		vdDisplayAt((22 - (strlen (szPAN))), inImamLineNumber-3, szPAN, CLR_EOL);
		vdDisplayAt(1, inImamLineNumber-2, "EXP[MMYY]: ", CLR_EOL);
		memset(buff, 0x00, sizeof(buff));
		strncat(buff, &szExpDate[2], 2);
		strncat(buff, &szExpDate[0], 2);
		vdDisplayAt((22 - (strlen (buff))), inImamLineNumber-2, buff, CLR_EOL);
		if(!strcmp(pobTran->srBRec.szPAN, szPAN)) {
			memcpy((char *) srISO.pszField35, szTrack2Data, TRACK2_SIZE);
			//return (VS_SUCCESS);
			retval=VS_SUCCESS;
			break;
		} else {
			DisplayStatus("CONFIRM CARD FAIL!");
			vdWarnBeep();
  			SVC_WAIT(2000);
		}
	} while (1);
	return retval;//(VS_ESCAPE);
}

int inImamSetAndCheckPrecompVoid(TRANSACTION_OBJECT* pobTran)
{
    LOG_PRINTFF((0x08L, "pobTran->srBRec.inCode = [%d]", pobTran->srBRec.inCode));      
	LOG_PRINTFF((0x08L, "pobTran->inTransactionCode = [%d]", pobTran->inTransactionCode));
	LOG_PRINTFF((0x08L, "pobTran->srTRTRec.TransactionCode = [%d]", pobTran->srTRTRec.TransactionCode));

	if (pobTran->srBRec.inCode == IMAM_PRECOMP) {
		if (pobTran->inTransactionCode != IMAM_PRECOMP_CANCEL){
			vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
			return(VS_ERR);
		}
	} else {
		if (pobTran->inTransactionCode == IMAM_PRECOMP_CANCEL){
			vdDisplayMessageFromFile( TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
			return(VS_ERR);
		}
	}

	return (VS_SUCCESS);
}

int inImamFunction(TRANSACTION_OBJECT *pobTran)
{
	return (VS_SUCCESS);
}

int inImamTestPrint(TRANSACTION_OBJECT *pobTran)
{
	extern PRINTER_OBJECT obPrinter;
	#ifndef IMAM_BNI
    char ucLineBuffer[24 + 1 + 1];
	    unsigned char *pucBuff;
	#endif

    int inBuffPtr = 0;
    
	{
		char    szPrinterCommand[6];	
        szPrinterCommand[0] = ESC;
        strcpy(&szPrinterCommand[1], "s");
		write (obPrinter.inHandle, szPrinterCommand, 2);
		//return VS_SUCCESS;
	}
	p350ColumnMode(COLUMN_TYPE_24);
    //shSpool(&obPrinter, "   TEST PRINT SUCCESS   \n");
    //shSpool(&obPrinter, "   TEST PRINT SUCCESS   \n");
    //shSpool(&obPrinter, "   TEST PRINT SUCCESS   \n");
	//shSpool(&obPrinter, "   TEST PRINT SUCCESS   \n");
	//shSpool(&obPrinter, "   TEST PRINT SUCCESS   \n");
    shSpool(&obPrinter, "\n\n\n\n\n\n");
	p350ColumnMode(COLUMN_TYPE_42);
    return (VS_SUCCESS);
}

int inImamPredial(TRANSACTION_OBJECT* pobTran)
{
	int inRetVal = VS_SUCCESS;
	int inResult;

	LOG_PRINTFF((0x08L, "FLOOR LIMIT = [%ld]", lnGetEMVFloorLimit()));

	if ((pobTran->srBRec.inChipStatus == EMV_CARD) && (lnGetEMVFloorLimit() > 0L)){
		return inRetVal;
	}
    if (pobTran->srBRec.inTranCardType != DEBIT_CARD && pobTran->srBRec.inTranCardType != EBT_CARD) {
        if (fGetDemoMode() != VS_TRUE) {
            if (!fGetOffline(pobTran) ) {
                if (fGetCreditPredial()) {
                    if (inGetFPSType() == FPS_NO) {
                        if (obCommunication.inBegin) {
                            if ((inResult = obCommunication.inBegin(&obCommunication, shGetCommunicationIndex(), VS_TRUE)) != VS_SUCCESS) {
								inRetVal = inResult;
                                if (lnGGErrorMessage() == 0)
                                    vdSGErrorMessage(PREDIAL_ERROR_MSG21);
                            }
                            pobTran->fPredialed = VS_TRUE;
                        }
                    }
                }
            }
        }
    }
    if (pobTran->srBRec.inTranCardType == DEBIT_CARD || pobTran->srBRec.inTranCardType == EBT_CARD) {
        if (fGetDemoMode() != VS_TRUE) {
            if (!fGetOffline(pobTran)) {
                if (fGetDebitPredial()) {
                    if (obCommunication.inBegin) {
                        if ((inResult = obCommunication.inBegin(&obCommunication, shGetCommunicationIndex(), VS_TRUE)) != VS_SUCCESS)
                            inRetVal = inResult;
                        pobTran->fPredialed = VS_TRUE;
                    }
                }
            }
        }
    }
	return (inRetVal);
}

unsigned short usImamAmtEntryFunc(unsigned long *lnAmountValue)
{
    char szAmount[AMT_SIZE + 1];
    int  inResult;
    int  inOpenAmount;
    char *szDisplaySymbol;
	#ifndef IMAM_BNI
	
    char szDisplayBuffer[DISP_STR_LEN + 1];
	#endif
    inOpenAmount = 0;

    lnGlobalAmount = 0;
    memset(szAmount, 0x00, sizeof (szAmount));
    vdDisplayMessageFromFile( AMT_MSG, ENTRY_MSG);
    szAmount[0] = '\0';

    szDisplaySymbol = szGetCurSymbol();
	//vdCustDisplayPrompt (AMT_MSG, VS_TRUE);
	if ((inResult = inImamCustGetAmount(szAmount, 1L, 999999999L, szDisplaySymbol, AMT_MSG)) != VS_SUCCESS)
		return(inResult);

    (*lnAmountValue) = lnGlobalAmount = atol(szAmount);
    return (EMV_SUCCESS);  //????KF long value putting to a short value.....
}

int inImamEMVAPIGetBaseAmount(TRANSACTION_OBJECT *pobTran)
{
	int inRet = VS_SUCCESS;
	//#ifdef IMAM_BNI
	unsigned short result;
	unsigned short tagLen;
	//#endif
	unsigned long ulAmt = 0L;
	char buff[256];

	LOG_PRINTFF((0x08L, "IMAM_EMV_GET_BASE_AMOUNT = inImamEMVAPIGetBaseAmount ============="));

	if (pobTran->inChipStatus == EMV_CARD) {
		if ((result = usEMVGetTLVFromColxn(TAG_9F02_AMT_AUTH_NUM, (byte *)&ulAmt, &tagLen)) != EMV_SUCCESS) {
			result = usImamAmtEntryFunc(&ulAmt);
			if(result != EMV_SUCCESS)
				return(result);
			LOG_PRINTFF((0x08L, "API : usEMVAddAmtToCollxn(%ld)", ulAmt));
			usEMVAddAmtToCollxn(ulAmt);
			{  //: Add to solve big Amount value of Indonesian currency
				unsigned short usLen;
				byte btTmp[32];
				memset (btTmp, 0x00, sizeof(btTmp));
				if (usEMVGetTLVFromColxn(TAG_9F02_AMT_AUTH_NUM, btTmp, &usLen) == EMV_SUCCESS)	{
					memmove(btTmp, &btTmp[1], 5); 
					btTmp[5] = 0x00;
					btTmp[6] = 0x00;
					usEMVUpdateTLVInCollxn(TAG_9F02_AMT_AUTH_NUM, btTmp, 6);

					memset(buff, 0x00, sizeof(buff));
					hex_2_asc((BYTE *)buff, btTmp, 6);
					LOG_PRINTFF((0x08L, "TAG(0x%X): EMVUpdateTLV[TAG_9F02_AMT_AUTH_NUM = %s]", TAG_9F02_AMT_AUTH_NUM, buff));	
				}
			}  
		}
		pobTran->srBRec.lnBaseTransactionAmount = lnGlobalAmount;
	} else {
		inRet = inRunFunction(pobTran, IMAM_CUST_GET_BASE_AMOUNT);
	}
	LOG_PRINTFF((0x08L, "IMAM_EMV_GET_BASE_AMOUNT = inImamEMVAPIGetBaseAmount ============= OK"));
    return (inRet);
}

int inImamEmvTag9f02Adjust(TRANSACTION_OBJECT *pobTran)
{
	int inRet = VS_SUCCESS;
	unsigned short result;
	unsigned short tagLen;
	unsigned long ulAmt = 0L;
	char buff[256];

	LOG_PRINTFF((0x08L, "IMAM_EMV_TAG9F02_ADJUST = inImamEmvTag9f02Adjust ================="));
	if (pobTran->inChipStatus == EMV_CARD) {
		ulAmt = pobTran->srBKey.lnTotalOfTransactionAmount;
		LOG_PRINTFF((0x08L, "API : usEMVAddAmtToCollxn(%ld)", ulAmt));
		usEMVAddAmtToCollxn(ulAmt);
		{  //: Add to solve big Amount value of Indonesian currency
			unsigned short usLen;
			byte btTmp[32];
			memset (btTmp, 0x00, sizeof(btTmp));
			if (usEMVGetTLVFromColxn(TAG_9F02_AMT_AUTH_NUM, btTmp, &usLen) == EMV_SUCCESS)	{
				if (inGetCurrencyIdx()){
				} else {
					memmove(btTmp, &btTmp[1], 5); 
					btTmp[5] = 0x00;
					btTmp[6] = 0x00;
				}
				usEMVUpdateTLVInCollxn(TAG_9F02_AMT_AUTH_NUM, btTmp, 6);
				memset(buff, 0x00, sizeof(buff));
				hex_2_asc((BYTE *)buff, btTmp, 6);
				LOG_PRINTFF((0x08L, "TAG(0x%X): EMVUpdateTLV[TAG_9F02_AMT_AUTH_NUM = %s]", TAG_9F02_AMT_AUTH_NUM, buff));	
			}  
		}
	} 

	if (pobTran->inChipStatus == EMV_CARD) { // : Set Currency code
		unsigned short usLen;
		byte btTmp[32];
		byte btTmp2[32];
		memset (btTmp, 0x00, sizeof(btTmp));
		memset (btTmp2, 0x00, sizeof(btTmp2));
		if (usEMVGetTLVFromColxn(TAG_5F2A_TRANS_CURCY_CODE, btTmp, &usLen) == EMV_SUCCESS)	{
			char buff[22];
			memset(buff, 0x00, sizeof(buff));
			if (inLoadCSTRec(inGetCurrencyIdx()) == VS_SUCCESS) {
				strcpy(buff, szGetCurCode());
				LOG_PRINTFF((0x08L, "CURRENCY=[%s]", buff));
				SVC_DSP_2_HEX((char *)buff, (char *)btTmp2, 2); //should be 2
				usEMVUpdateTLVInCollxn(TAG_5F2A_TRANS_CURCY_CODE, btTmp2, 2);
				memset(buff, 0x00, sizeof(buff));
				hex_2_asc((BYTE *)buff, btTmp2, 2);
				LOG_PRINTFF((0x08L, "TAG(0x%X): EMVUpdateTLV[TAG_5F2A_TRANS_CURCY_CODE = %s]", TAG_5F2A_TRANS_CURCY_CODE, buff));	
			}
		}  
	}

	if (pobTran->inChipStatus == EMV_CARD) {
	{
		char chImamBuffer[128];
		int  inResult;
		int  i;

		memset(chImamBuffer, 0x00, sizeof(chImamBuffer));
		inResult = SVC_INFO_SERLNO(chImamBuffer);
		if (inResult) {
			memset(chImamBuffer, 0x00, sizeof(chImamBuffer));
  			inResult = get_env("TERMSERNUM", chImamBuffer, sizeof(chImamBuffer));
			if(inResult <= 0) {
       			strcpy(chImamBuffer, "10102397");
			}
		}
		for (i=0; i<strlen(chImamBuffer); i++) {
			if (!isdigit(chImamBuffer[i])) {
				strcpy(&chImamBuffer[i], &chImamBuffer[i+1]);
				i--;
			}
		}
		if (strlen(chImamBuffer)>8) {
			strcpy(chImamBuffer, &chImamBuffer[strlen(chImamBuffer)-8]);
		}
		LOG_PRINTFF((0x08L, "EDC SN : [%s]", chImamBuffer));

#ifdef IMAM_PERMATA //Permata Req : EDCDIC for Visa, Ascii for MasterCard. //BNI: req Ascii
		if (inGetIssuerNum()==1){ //VISA
			LOG_PRINTFF((0x08L, "VISA ==> MAKE IT EBCDIC"));
			for (i=0; i<strlen(chImamBuffer); i++) { chImamBuffer[i] = chImamBuffer[i] + 192; } //make it EBCDIC
		}
#endif
		{
			char buff[256];
			memset(buff, 0x00, sizeof(buff));
			usEMVAddTLVToCollxn(TAG_9F1E_IFD_SER_NUM , (byte *)chImamBuffer, strlen(chImamBuffer));
			//if (strlen(chImamBuffer)>0) hex_2_asc((BYTE *)buff, chImamBuffer, strlen(chImamBuffer));
			//LOG_PRINTFF((0x08L, "TAG(0x%X): EMVAddTLV [TAG_9F1E_IFD_SER_NUM = %s]", TAG_9F1E_IFD_SER_NUM, buff));
		}
	}  //end of add
	}

	LOG_PRINTFF((0x08L, "IMAM_EMV_TAG9F02_ADJUST = inImamEmvTag9f02Adjust ================= OK"));
    return (inRet);
}

int inImamEmvTcUpload(TRANSACTION_OBJECT *pobTran) 
{
	int inRet = VS_SUCCESS;
	LOG_PRINTFF((0x08L, "IMAM_EMV_TC_UPLOAD = inImamEmvTcUpload ==========================="));
	if ((fImamNeedToSendTC==VS_TRUE) && (pobTran->srBRec.inChipStatus == EMV_CARD) && 
		(pobTran->srBRec.inTransactionResult == HOST_AUTHORISED || pobTran->srBRec.inTransactionResult == AUTHORIZED) && 
		(pobTran->srTRTRec.TransactionCode==SALE || pobTran->srTRTRec.TransactionCode == CITI_EPP_SALE || pobTran->srTRTRec.TransactionCode==PRE_AUTH || pobTran->srTRTRec.TransactionCode==AUTH_ONLY || pobTran->srTRTRec.TransactionCode==IMAM_CARDVER)
		){
		char szTcUpload[128];
		memset(szTcUpload, 0x00, sizeof(szTcUpload));
		szTcUpload[get_env("EMV.TCUPLOAD" , szTcUpload , 1)]=0x00 ;
		LOG_PRINTFF((0x08L, "SENDING TC..."));
		if (szTcUpload[0] == '1' ) {
			inImamSendOrSaveTC(pobTran);
		}
	}
	fImamNeedToSendTC = VS_FALSE;
	LOG_PRINTFF((0x08L, "IMAM_EMV_TC_UPLOAD = inImamEmvTcUpload =========================== OK"));
	return (inRet);
}

int inImamSendOrSaveTC(TRANSACTION_OBJECT *pobTran)
{
	int inRetval = VS_SUCCESS;
    short inMyTranCode;
    short inPIPTransCode;
	char buff[128];
    PACKET_OBJECT obPacket;

	short inCode = pobTran->srBRec.inCode;
	short inTransactionCode = pobTran->inTransactionCode;
	short TransactionCode = pobTran->srTRTRec.TransactionCode;
	
	{//MARK THERE IS A TC ...
		memset(buff, 0x00, sizeof(buff));
		strcpy(buff, "1");
		vdSetTCFlag(&pobTran->srBRec, (unsigned char *)buff);
		//vdGetTCFlag(&pobTran->srBRec, (unsigned char *)buff);
	}
	DisplayStatus("SENDING TC...");
    if (fGetDemoMode() == VS_TRUE) {
        return (VS_SUCCESS);
    }
    if ((psrHostData = psrCreateHostData()) == (HOST_8583_DATA *) NULL_CH) {
        vdFreeHostData(psrHostData);
        vdFreeVariantTables();
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        return (VS_ERR);
    }
	inIncSTAN();
    pobTran->srBRec.lnSTAN = lnGetSTAN();

    if (inInitializePacket(&obPacket) != VS_SUCCESS) { //Do we need?
        return(VS_ERR);
    }
    if (obPacket.inInitialize(&obPacket) != VS_SUCCESS) {//Do we need?
        return(VS_ERR);
    }
    if ((psrHostData->c8583_data = psrCreateCommData(pobTran, CPAC_SEND_SIZE, VS_FALSE /*VS_TRUE*/)) == (COMM_8583_DATA *) NULL_CH) {
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        vdFreeISO8583Data(psrHostData);
        return (VS_ERR);
    }
	psrHostData->c8583_data->transceiver = inImamTxRx8583;  //
#ifdef MODEM
	if (inGetUCLCommLink()==0) {  // to get resp timeout
		MODEM_OBJECT *obModem;
		obModem = (MODEM_OBJECT *)obCommunication.Data;
		psrHostData->c8583_data->comm_timeout         = obModem->shGetRespTimeOut(obModem->srCPT);  // for Response TimeOut
		psrHostData->c8583_data->wait_for_carrier     = obModem->shGetCarrierTimeOut(obModem->srCPT); // for Carier TimeOut
	}
#endif
    ((VALIDATION_STRUCT *) (psrHostData->c8583_data->v_parms))->comm_struct = psrHostData->c8583_data;
	psrHostData->c8583_data->validation = (PFI_PVOID_INT) inCPACBaseRespValidation; 
	psrHostData->reverse_flag = VS_FALSE; // Disable reversal ?

	{//to make this trx so that can be upload as offline trx before settle?
		//vdSetOffline(pobTran, VS_TRUE);
		//pobTran->srBKey.fOffline = VS_TRUE;
		//pobTran->srBRec.fCustNum = VS_TRUE;
		//vdGetReversalFileName((char *)stRevFileName, inGetHostHandle());
	}

	obPacket.inError = 0;			
    pobTran->srBRec.inCode = TC_UPLOAD; //vdSGCode(IMAM_ECHO);     
	pobTran->inTransactionCode = TC_UPLOAD;
	pobTran->srTRTRec.TransactionCode = TC_UPLOAD;

	//inMyTranCode = shVerifyCPACTransType(pobTran);  
    inMyTranCode = TC_UPLOAD;
    inStoreTranFlexiData(pobTran, AMEX_PIP_TRANS_CODE, (unsigned char *) &inMyTranCode, 2);

	LOG_PRINTFF((0x08L, "AFTER STORE TRAN"));
	
    if ((inPIPTransCode = shLoadPIPTransCode(inMyTranCode)) == VS_ERR) {
        vdFreeISO8583Data(psrHostData);
		pobTran->srBRec.inCode = inCode;
		pobTran->inTransactionCode = inTransactionCode;
		pobTran->srTRTRec.TransactionCode = TransactionCode;
        return (VS_ERR);
    }

	vdDispMsgAt(WAIT_MSG, 1, inImamLineNumber, CLR_EOL);
	errno = 0;

	LOG_PRINTFF((0x08L, "BEFORE PIP_TRAN"));
	DisplayStatus("SENDING TC... ...");
	inRetval = pip_trans(inPIPTransCode, psrHostData);    
	vdFreeISO8583Data(psrHostData);
	if ((inRetval == PIP_APPROVAL) && (!strncmp((char *) srISO.pszField39, "00", 2))) {
		LOG_PRINTFF((0x08L, "SEND TC OK"));
		{//MARK THERE IS NO MORE TC ...
			memset(buff, 0x00, sizeof(buff));
			vdSetTCFlag(&pobTran->srBRec, (unsigned char *)buff);
		}
    } else {
		LOG_PRINTFF((0x08L, "SEND TC FAIL...THEN SAVE IT"));
    }
	{//return it to original one 
		pobTran->srBRec.inCode = inCode;
		pobTran->inTransactionCode = inTransactionCode;
		pobTran->srTRTRec.TransactionCode = TransactionCode;
	}
	{//DO THIS REALLY SEND THE TC?
		//DisplayStatus("SENDING TC... WAIT");
		//LOG_PRINTFF((0x08L, "SEND TC FAIL...AS OFFLINE"));
		//pobTran->srBRec.fCustNum = VS_FALSE ;
		//vdChangeRocordToTop(pobTran);
		//vdCheckRecInROCADV( pobTran );
		//if (inUploadCPACAdvices(VS_FALSE,pobTran) == VS_SUCCESS) {
		//pobTran->srBKey.fOffline = VS_FALSE;
		//    pobTran->srBKey.fOffline = VS_FALSE;
		//    pobTran->srBRec.lnOrigTotalTransactionAmount = pobTran->srBKey.lnTotalOfTransactionAmount;
		//} else {
		//	ACTIVITY_LOG("TC UpLoad Fail ..");
		//}
	}
	{ //LIEM
		inImamModifyCurrentBatchRec(pobTran);
	}
	return VS_SUCCESS;
}



int inEditPCLOperation(TRANSACTION_OBJECT* pobTran) {
    inConfRecEdit("PCL");
    return(BRANCH_EXIT);
}

int inEditCTLOperation(TRANSACTION_OBJECT* pobTran) {
    inConfRecEdit("CTL");
    return(BRANCH_EXIT);
}

int inImamKeepCommUp (TRANSACTION_OBJECT *pobTran)
{
	LOG_PRINTFF((0x08L, "--IMAM_KEEP_COMM_UP--"));

	if (fGetDemoMode()) return VS_SUCCESS;
	if (!fGetOffline(pobTran)){
		LOG_PRINTFF((0x08L, "IMAM==>ONLINE TRANSACTION"));
		if(pobTran->fPredialed != VS_TRUE){ //edi from pak 
			if (obCommunication.inBegin) {
                            if ((obCommunication.inBegin(&obCommunication, shGetCommunicationIndex(), VS_TRUE)) != VS_SUCCESS) {
					 if (lnGGErrorMessage() == 0)
                                    vdSGErrorMessage(PREDIAL_ERROR_MSG21);
                            }
                            pobTran->fPredialed = VS_TRUE;
                    }
	       }
		
		if (obCommunication.inCheck) { 
			if (obCommunication.inCheck(&obCommunication) != VS_SUCCESS) {
				return(VS_ERR);
			}
		}
		LOG_PRINTFF((0x08L, "COMM CONNECTED AND WILL BE KEPT..."));
		fImamKeepCommUp = VS_TRUE;
	} else {
		LOG_PRINTFF((0x08L, "IMAM==>OFFLINE TRANSACTION"));
		fImamKeepCommUp = VS_FALSE;
		obCommunication.inEnd(&obCommunication);  //MUST BE ENDED OR CRASHING...
	}
	inImamRestartFlag++;
	return VS_SUCCESS;
}

int inImamKeepCommUpEnd (TRANSACTION_OBJECT *pobTran)
{
	LOG_PRINTFF((0x08L, "--IMAM_KEEP_COMM_UP--END"));
	if (fImamKeepCommUp == VS_TRUE){
		LOG_PRINTFF((0x08L, "--inImamKeepCommEnd--"));
		fImamKeepCommUp = VS_FALSE;
		vdDispMsgAt(WAIT_MSG, 1, inImamLineNumber, CLR_EOL);
		obCommunication.inEnd(&obCommunication);
	}
	return VS_SUCCESS;
}

int inImamKeepCommUpEndIdle (TRANSACTION_OBJECT *pobTran)
{
	if (fImamKeepCommUp == VS_TRUE){
		fImamKeepCommUp = VS_FALSE;
		vdDispMsgAt(WAIT_MSG, 1, inImamLineNumber, CLR_EOL);
		obCommunication.inEnd(&obCommunication);
		//inEventResponder(IMAMM_SEND_REVERSAL);
		vdImamDisplayMenu(4);
	}
	return VS_SUCCESS;
}

int inImamInitComDevice (TRANSACTION_OBJECT *pobTran)
{
	return VS_SUCCESS;
//	return inImamOpenComDevice();
}


int inImamSaleContactless (TRANSACTION_OBJECT *pobTran)
{
	return VS_SUCCESS;
}

int inImamMifareFunction(TRANSACTION_OBJECT *pobTran)
{

	return VS_SUCCESS;
}

int inImamSaleCTLThanksWelcome(TRANSACTION_OBJECT *pobTran)
{

	return VS_SUCCESS;
}

int inImamSaleMifare (TRANSACTION_OBJECT *pobTran)
{
	return VS_SUCCESS;
	
}

int inImamSaleSCard (TRANSACTION_OBJECT *pobTran)
{
	//inImamSCard();
	return VS_SUCCESS;
}

int inImamSetContaclessPRM (TRANSACTION_OBJECT *pobTran)
{

return VS_SUCCESS;
}

int inImamSetContaclessMSG (TRANSACTION_OBJECT *pobTran)
{

return VS_SUCCESS;
}
int inImamSetContaclessCAPK (TRANSACTION_OBJECT *pobTran)
{

return VS_SUCCESS;
}

int inImamDummy(TRANSACTION_OBJECT *pobTran)
{

	return VS_SUCCESS;
}

int inImamEMVSendReversal(TRANSACTION_OBJECT *pobTran)  //Simplify this...
{	return VS_SUCCESS;
}

int inImamSendInquiry(TRANSACTION_OBJECT *pobTran)
{
	int inRetval = VS_SUCCESS;
    short inMyTranCode;
    short inPIPTransCode;
	char buff[128];
    PACKET_OBJECT obPacket;

	short inCode = pobTran->srBRec.inCode;
	short inTransactionCode = pobTran->inTransactionCode;
	short TransactionCode = pobTran->srTRTRec.TransactionCode;

	memset(buff, 0x00, sizeof(0x00));

	//if (ImamActiveMenu->inDataID != 11) return (VS_SUCCESS);
    if (fGetDemoMode() == VS_TRUE) return (VS_SUCCESS);

    if (obCommunication.inCheck) {
        if (obCommunication.inCheck(&obCommunication) != VS_SUCCESS) {
            return(VS_ERR);
        }
	}

    if ((psrHostData = psrCreateHostData()) == (HOST_8583_DATA *) NULL_CH) {
        vdFreeHostData(psrHostData);
        vdFreeVariantTables();
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        return (VS_ERR);
    }

	inIncSTAN();
    pobTran->srBRec.lnSTAN = lnGetSTAN();

    if (inInitializePacket(&obPacket) != VS_SUCCESS) {
        return(VS_ERR);
    }

    if (obPacket.inInitialize(&obPacket) != VS_SUCCESS) {
        return(VS_ERR);
    }

    if ((psrHostData->c8583_data = psrCreateCommData(pobTran, CPAC_SEND_SIZE, VS_FALSE /*VS_TRUE*/)) == (COMM_8583_DATA *) NULL_CH) {
        vdSGErrorMessage(NO_MEM_ERR_MSG);
        vdFreeISO8583Data(psrHostData);
        return (VS_ERR);
    }

	psrHostData->c8583_data->transceiver = inImamTxRx8583;  //
#ifdef MODEM
	if (inGetUCLCommLink()==0) {  // to get resp timeout
		MODEM_OBJECT *obModem;
		obModem = (MODEM_OBJECT *)obCommunication.Data;
		psrHostData->c8583_data->comm_timeout         = obModem->shGetRespTimeOut(obModem->srCPT);  // for Response TimeOut
		psrHostData->c8583_data->wait_for_carrier     = obModem->shGetCarrierTimeOut(obModem->srCPT); // for Carier TimeOut
	}
#endif

    ((VALIDATION_STRUCT *) (psrHostData->c8583_data->v_parms))->comm_struct = psrHostData->c8583_data;
	psrHostData->c8583_data->validation = (PFI_PVOID_INT) inCPACBaseRespValidation; 
	psrHostData->reverse_flag = VS_FALSE; // Disable reversal ?

	obPacket.inError = 0;			
    pobTran->srBRec.inCode = IMAM_SFT_INQUIRY; 
	pobTran->inTransactionCode = IMAM_SFT_INQUIRY;
	pobTran->srTRTRec.TransactionCode = IMAM_SFT_INQUIRY;

	//inMyTranCode = shVerifyCPACTransType(pobTran);  
    inMyTranCode = IMAM_SFT_INQUIRY;
    inStoreTranFlexiData(pobTran, AMEX_PIP_TRANS_CODE, (unsigned char *) &inMyTranCode, 2);

	LOG_PRINTFF((0x08L, "AFTER STORE TRAN"));
	
    if ((inPIPTransCode = shLoadPIPTransCode(inMyTranCode)) == VS_ERR) {
        vdFreeISO8583Data(psrHostData);
		pobTran->srBRec.inCode = inCode;
		pobTran->inTransactionCode = inTransactionCode;
		pobTran->srTRTRec.TransactionCode = TransactionCode;
        return (VS_ERR);
    }

	vdDispMsgAt(WAIT_MSG, 1, inImamLineNumber, CLR_EOL);
	errno = 0;

	LOG_PRINTFF((0x08L, "BEFORE PIP_TRAN"));

	inRetval = pip_trans(inPIPTransCode, psrHostData);    
	vdFreeISO8583Data(psrHostData);
	
    if (inRetval != PIP_APPROVAL) {
		if (obCommunication.inEnd) obCommunication.inEnd(&obCommunication);
		DisplayStatus("INQUIRY FAIL!");
		SVC_WAIT(2000);
		return VS_ERR;
	} else if ((inRetval == PIP_APPROVAL) && (!strncmp((char *) srISO.pszField39, "00", 2))) {
		vdDisplayAt(1, inImamLineNumber-1, "CHARGED:", CLR_EOL);
		if (inHorizontalMenuChoice("", "LANJUT", "", "", "BATAL") == 1){
		} else {
			if (obCommunication.inEnd) obCommunication.inEnd(&obCommunication);
			return VS_ESCAPE;
		}
		//SUCCESS ACTION HERE
    } else {
		if (obCommunication.inEnd) obCommunication.inEnd(&obCommunication);
		DisplayStatus("INQ FAIL!");
		SVC_WAIT(2000);
		return VS_ERR;
    }
	{//return it to original one 
		pobTran->srBRec.inCode = inCode;
		pobTran->inTransactionCode = inTransactionCode;
		pobTran->srTRTRec.TransactionCode = TransactionCode;
	}
	return VS_SUCCESS;
}

int inImamSendPiggyBack(TRANSACTION_OBJECT *pobTran)
{
	int inRetval = VS_SUCCESS;
	if (fGetDemoMode()) return VS_SUCCESS;
	if (!fGetImamHostPiggyBack()) return inRetval;

	if (!fGetOffline(pobTran)){
		if (obCommunication.inCheck) {
			if (obCommunication.inCheck(&obCommunication) != VS_SUCCESS) {
				return(VS_ERR);
			}
		}
		LOG_PRINTFF((0x08L, "DO PIGGY BACK"));
		{
			PACKET_OBJECT obPacket;
			if (inInitializePacket(&obPacket) != VS_SUCCESS) {
				return(VS_ERR);
			}
			vdOverLoadLoadDataFuncs(srCITILoadDataFuncs);
			inOverloadFieldID(INIT_VALIDATION_STRUCT, (PFI_TO) inInitializeCPACValidationStruct);
			inOverloadFieldID(MODIFY_BATCH_REC, inModifyCPACBatchRec);
			inOverloadFieldID(SET_TRANS_FIELDS, (PFI_TO) inSetCITITransFields);
			inOverloadFieldID(UPDATE_REVERSAL, (PFI_TO) inUpdateCPACReversal);   // CPAC_UNBKL added
			memset(srISO.pszField37, 0, sizeof(srISO.pszField37));  // CPAC_UNBKL added
			memset(srISO.pszField38, 0, sizeof(srISO.pszField38));  // CPAC_UNBKL added
		}
		inRetval = inUploadCPACAdvices(VS_FALSE, pobTran);
		LOG_PRINTFF((0x08L, "DO PIGGY BACK ======= END"));
	} 
	return inRetval;
}

int inImamGetTDesPin(TRANSACTION_OBJECT *pobTran)
{
	if (pobTran->srBRec.inTranCardType == DEBIT_CARD && fGetPinpadRequired){
		if (inGet3DESPin( (unsigned char *)pobTran->srBRec.szPAN, (unsigned char *)pobTran->szPIN) == 0) return VS_ESCAPE;
	}
		return VS_SUCCESS;
}

/*
int inGet3DESPin(unsigned char *szPAN, unsigned char *ePIN)
{
	unsigned char MKey[49];
	unsigned char WKey[49];
	unsigned char bcdMKey[25];
	unsigned char bcdWKey[25];
	unsigned char bcdPINKey[49];
	unsigned char szPin[10];
	unsigned char bcdPinFormat[9];
	unsigned char bcdPAN[9];
	unsigned char bcdPinBlock[9];
	unsigned char bcdEPIN[9];
	unsigned char szBuff[64];

	memset(MKey, 0x00, sizeof(MKey));
	memset(WKey, 0x00, sizeof(WKey));
	memset(szPin, 0x00, sizeof(szPin));
	if (InputPIN("ENTER PIN:", szPin, 4, 6) == 0) return 0;
	{
		memset(szBuff, 0x00, sizeof(szBuff));
		memset(bcdPinFormat, 0x00, sizeof(bcdPinFormat));
		sprintf(szBuff, "%02d%s", strlen(szPin), szPin);
		memset(&szBuff[strlen(szBuff)], 'F', 16-strlen(szBuff));
		SVC_DSP_2_HEX(szBuff, bcdPinFormat, 8);
	}
	{
		memset(szBuff, 0x00, sizeof(szBuff));
		memset(bcdPAN, 0x00, sizeof(bcdPAN));
		strcpy(szBuff, szPAN);
		memmove(&szBuff[4], &szBuff[3], 12);
		memset(szBuff, '0', 4);
		SVC_DSP_2_HEX(szBuff, bcdPAN, 8);
	}
	{
		int i=0;
		memset(bcdPinBlock, 0x00, sizeof(bcdPinBlock));
		for (i = 0; i<8; i++) bcdPinBlock[i] = bcdPinFormat[i] ^ bcdPAN[i];
	}

	{
		memset(bcdPINKey, 0x00, sizeof(bcdPINKey));
		strcpy(MKey, "DCD5014397AE79FE1F5779BC94076D52");
		strcpy(WKey, "FAAF78784193C6C82E44FB454BE8214F"); 
		SVC_DSP_2_HEX(MKey, bcdMKey, strlen(MKey)/2);     
		SVC_DSP_2_HEX(WKey, bcdWKey, strlen(WKey)/2);
	}
	if (strlen(WKey) == 16){
		inImamDES_SD(bcdMKey, bcdWKey, bcdPINKey);	
		inImamDES_SE(bcdPINKey, bcdPinBlock, bcdEPIN);
	} else if (strlen(WKey) == 32){
		inImamDES_DD(bcdMKey, &bcdWKey[0], &bcdPINKey[0]);	
		inImamDES_DD(bcdMKey, &bcdWKey[8], &bcdPINKey[8]);	
		inImamDES_DE(bcdPINKey, bcdPinBlock, bcdEPIN);
	} else {
		inImamDES_TD(bcdMKey, &bcdWKey[0], &bcdPINKey[0]);	
		inImamDES_TD(bcdMKey, &bcdWKey[8], &bcdPINKey[8]);	
		inImamDES_TD(bcdMKey, &bcdWKey[16], &bcdPINKey[16]);	
		inImamDES_DE(bcdPINKey, bcdPinBlock, bcdEPIN);
	}
	SVC_HEX_2_DSP(bcdEPIN, ePIN, 8);
	return 1;
}
*/
int inImamSetTrxOffline(TRANSACTION_OBJECT *pobTran)
{
	if ((pobTran->inTransactionCode == REFUND) &&(fGetImamHostOffineRefund() == VS_TRUE)){
		pobTran->srBRec.inCode = REFUND_OFFLINE;
		pobTran->srTRTRec.TransactionCode = REFUND_OFFLINE;
	}
	if( ((pobTran->srBRec.inCode == SALE_OFFLINE) && (pobTran->srBKey.fVoided == VS_TRUE)) ||
		//((pobTran->srBRec.lnTipAmount != 0L) && (pobTran->srBKey.fVoided == VS_TRUE)) ||
		(pobTran->srTRTRec.TransactionCode == ADJUST) ||
		(pobTran->srTRTRec.TransactionCode == CPAC_PHIL_ADJUST) ||
		(pobTran->srTRTRec.TransactionCode == TIP_ADJUST) ||
		(pobTran->srTRTRec.TransactionCode == ADD_TIP_OFFLINE) ||
		((fGetImamHostOfflineVoid() == VS_TRUE) && (pobTran->srBKey.fVoided)) ||
		((fGetImamHostOffineRefund() == VS_TRUE) && (pobTran->inTransactionCode == REFUND)) ||
		(pobTran->srBRec.inCode == REFUND_OFFLINE)
		) {
		pobTran->srTRTRec.Offline = VS_TRUE;
		if ((pobTran->srBRec.inCode == REFUND_OFFLINE) && (!fGetImamHostOfflineVoid())) {
			if (pobTran->srBKey.fUploaded && pobTran->srBKey.fVoided){
				pobTran->srBRec.inCode = REFUND;
				pobTran->srTRTRec.Offline = VS_FALSE;
			}
		}
		if ((pobTran->srBRec.inCode == SALE_OFFLINE) && (!fGetImamHostOfflineVoid())){
			if (pobTran->srBKey.fUploaded && pobTran->srBKey.fVoided){
				pobTran->srBRec.inCode = SALE;
				pobTran->srTRTRec.Offline = VS_FALSE;
			}
		}
	} else {
		pobTran->srTRTRec.Offline = VS_FALSE;
	}
	return(VS_SUCCESS);
}

int inImamDownloadLogo(int inLogoID)
{
	static unsigned int inCurrentLogoID = 100; //undefined logo
	int h_font_file=0;
	char szLogoFile[30];

	if (inLogoID != inCurrentLogoID){
		memset(szLogoFile, 0x00, sizeof(szLogoFile));
		if (inLogoID != 99) {
			strcpy(szLogoFile, "F:");
			strcat(szLogoFile, szGetLGOFileName());
			strcat(szLogoFile, ".LGO");
		}
		if ((inLogoID == 99) || (strlen(szLogoFile)==6)) strcpy(szLogoFile, "F:NoLogo.lgo");
		h_font_file = open(szLogoFile, O_RDONLY);
	}
	if (h_font_file>0 && obPrinter.inHandle>0) {
		p3300_dnld_graphic_file (obPrinter.inHandle, h_font_file);
		//if success, or consider success
		inCurrentLogoID = inLogoID;
		LOG_PRINTFF((0x08L, "LOGO DOWNLOADED"));
	} else {
		LOG_PRINTFF((0x08L, "LOGO NOT DOWNLOADED"));
	}
	return VS_SUCCESS;
}

int inImamDownloadHostLogo(TRANSACTION_OBJECT *pobTran)
{
	return inImamDownloadLogo(shGetHostGroupRef());
}

int inImamDownloadBlankLogo()
{
	return inImamDownloadLogo(99);
}



/* dota_license */

void ascii2bcd(unsigned char *ascii, unsigned char *bcd)
{
	unsigned int i, j;

	for ( i=0, j=0; i<strlen((char*)ascii); i++ )
	{
		char first = ascii[i];
		char second= ascii[++i];
		if ( first>='a' ) first = first - 'a' + 10;
		else if ( first>='A' ) first = first - 'A' + 10;
		else first = first - '0';
		if ( second>='a' ) second = second - 'a' + 10;
		else if ( second >='A' ) second = second  - 'A' + 10;
		else second = second  - '0';
		bcd[j++] = (char)(first*16+second);
	}
}

void bcd2ascii(unsigned char *bcd, unsigned char *ascii, int bcd_len)
{
	int i, size;
	char tmp[512];
	char cs[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

	memset(tmp, '\0', sizeof(tmp));

	size = bcd_len;
	if ( size>sizeof(tmp)/2 )
	{
		size = sizeof(tmp)/2;
	}

	for ( i=0; i<size; i++ )
	{
		tmp[i*2] 	= cs[ bcd[i]>>4 & 0x0F];
		tmp[i*2+1] = cs[ bcd[i] & 0x0F];
	}

	memcpy(ascii, tmp, strlen(tmp));
}

/*
** DES encryption/decryption functions
*/

#define	F(l,r,key1,key2){                   \
	work = ((r >> 4) | (r << 28)) ^ key1;	\
	l ^= Spbox[6][work & 0x3f];		        \
	l ^= Spbox[4][(work >> 8) & 0x3f];	    \
	l ^= Spbox[2][(work >> 16) & 0x3f];	    \
	l ^= Spbox[0][(work >> 24) & 0x3f];	    \
	work = r ^ key2;			            \
	l ^= Spbox[7][work & 0x3f];		        \
	l ^= Spbox[5][(work >> 8) & 0x3f];	    \
	l ^= Spbox[3][(work >> 16) & 0x3f];	    \
	l ^= Spbox[1][(work >> 24) & 0x3f];	    \
}

int getEPin(unsigned char *master, unsigned char *working, unsigned char *card, unsigned char *pin, unsigned char *ePin)
{
	unsigned char buff[40], buff2[40], buff3[40];
	unsigned char masterKey[40], workingKey[40], fPin[40], fCard[40];
	unsigned char pinKey[40], pinBlock[40];
	#ifndef IMAM_BNI
	unsigned long key[16][2];
	#endif
	int i;
	
	// get pinKey
	memset(buff, '\0', sizeof(buff));
	memset(masterKey, '\0', sizeof(masterKey));
	memset(workingKey, '\0', sizeof(workingKey));
	memset(pinKey, '\0', sizeof(pinKey));
	ascii2bcd(master, masterKey);
	ascii2bcd(working, workingKey);

	inImamDES_SD(masterKey, workingKey, buff);

//	desSetKey(key, masterKey, 1);
//	desEncrypt(key, workingKey);
//	memcpy(buff, workingKey, 8);

	bcd2ascii(buff, pinKey, 8);

	// get fPin
	memset(buff, '\0', sizeof(buff));
	memset(fPin, '\0', sizeof(fPin));
	sprintf((char*)buff, "%02d", strlen((char *)pin));
	strcat((char*)fPin, (char *)buff);									
	strcat((char*)fPin, (char *)pin);									
	memset(&(fPin[strlen((char *)pin)+2]), 'F', 16-strlen((char *)fPin));
			
	// get fCard
	memset(buff, '\0', sizeof(buff));
	memset(fCard, '\0', sizeof(fCard));
	strncpy((char *)buff, (char *)&card[3], 12);
	strcat((char *)fCard, "0000");
	strcat((char *)fCard, (char *)buff);

	// get pinBlock
	memset(buff, '\0', sizeof(buff));
	memset(buff2, '\0', sizeof(buff2));
	memset(pinBlock, '\0', sizeof(pinBlock));
	ascii2bcd(fPin, buff);
	ascii2bcd(fCard, buff2);	
	for (i=0; i<8; i++)
		pinBlock[i] = buff[i] ^ buff2[i];		
	memset(buff, '\0', sizeof(buff));
	bcd2ascii(pinBlock, buff, 8);
	memset(pinBlock, '\0', sizeof(pinBlock));
	strcpy((char *)pinBlock, (char *)buff);

	// get ePin
	memset(buff, '\0', sizeof(buff));
	memset(buff2, '\0', sizeof(buff2));
	memset(buff3, '\0', sizeof(buff3));
	memset(ePin, '\0', sizeof(ePin));
	ascii2bcd(pinKey, buff);
	ascii2bcd(pinBlock, buff2);

	inImamDES_SE(buff, buff2, buff3);

//	desSetKey(key, buff, 0);
//	desEncrypt(key, buff2);
//	memcpy(buff3, buff2, 8);

	bcd2ascii(buff3, ePin, 8);
  
	
	return 1;
}

int fImamCheckLisense(void) 
{
	
	return 1;
	}

int
fImamSetLisense(char* szLicenseKey) 
{


	return 1;
}


int inCalculatePin(unsigned char *szPAN, char * PINInput,unsigned char *ePIN)
{
	unsigned char MKey[49];
	unsigned char WKey[49];
	unsigned char bcdMKey[25];
	unsigned char bcdWKey[25];
	unsigned char bcdPINKey[49];
	unsigned char szPin[10];
	unsigned char bcdPinFormat[9];
	unsigned char bcdPAN[9];
	unsigned char bcdPinBlock[9];
	unsigned char bcdEPIN[9];
	unsigned char szBuff[64];
//	unsigned char Bufferme[32];

 
	memset(MKey, 0x00, sizeof(MKey));
	memset(WKey, 0x00, sizeof(WKey));
	memset(szPin, 0x00, sizeof(szPin));
	
	memset(szBuff, 0x00, sizeof(szBuff));
	memset(bcdPinFormat, 0x00, sizeof(bcdPinFormat));
		
		memset(&szBuff[strlen((char *)szBuff)], 'F', 16-strlen((char *)szBuff));
		sprintf((char *)szBuff, "%02d%s", strlen((char *)PINInput), PINInput);
		  SVC_DSP_2_HEX((char *)szBuff, (char *)bcdPinFormat, 8);
	
	{
		memset(szBuff, 0x00, sizeof(szBuff));
		memset(bcdPAN, 0x00, sizeof(bcdPAN));
		strcpy((char *)szBuff, (char *)szPAN);
		
		memmove(&szBuff[4], &szBuff[3], 12);
		memset(szBuff, '0', 4);
		SVC_DSP_2_HEX((char *)szBuff, (char *)bcdPAN, 8);
	}
	{
		int i=0;
		memset(bcdPinBlock, 0x00, sizeof(bcdPinBlock));
		for (i = 0; i<8; i++) 
			bcdPinBlock[i] = bcdPinFormat[i] ^ bcdPAN[i];
	}

		memset(bcdPINKey, 0x00, sizeof(bcdPINKey));


		fImamGetMKey3D(MKey); 
		fImamGetWKey3D(WKey);
	
		SVC_DSP_2_HEX((char *)MKey, (char *)bcdMKey, strlen((char *)MKey)/2);     
		SVC_DSP_2_HEX((char *)WKey, (char *)bcdWKey, strlen((char *)WKey)/2);

      if ((strlen((char *)WKey) == 0) ||(strlen((char *)MKey) == 0))//imam Check For The Working Not Loaded
      	{ vdDisplayMessageFromFile( KTK_MASTER_MSG, ERROR_MSG);
      	 vdWarnBeep();
      	 SVC_WAIT(1000);
	  	
      	 return 0;
      	}
	if (strlen((char *)WKey) == 16){
		
				
		inImamDES_SD(bcdMKey, bcdWKey, bcdPINKey);// decryprt the working Key 
		 inImamDES_SE(bcdPINKey, bcdPinBlock, bcdEPIN);// encrypt the Pin with clear working key
		
	} else if (strlen((char *)WKey) == 32){
	
//bcdMKey Clear TMK : 2E5CA0248DF930C3B8EEEE6539DBDBC0
//bcdWKey TPK(TMK)  : 86A33F9D828B2AFE7251A4C1908B378D
//clear TPK : 62D32C262538DA34E96E520B7CEC256B
	
	    //TPK(TMK)== bcdMKey
		inImamDES_DD(bcdMKey, &bcdWKey[0], &bcdPINKey[0]);	
		inImamDES_DD(bcdMKey, &bcdWKey[8], &bcdPINKey[8]);	
		inImamDES_DE(bcdPINKey, bcdPinBlock, bcdEPIN);
	} else {
		inImamDES_TD(bcdMKey, &bcdWKey[0], &bcdPINKey[0]);	
		inImamDES_TD(bcdMKey, &bcdWKey[8], &bcdPINKey[8]);	
		inImamDES_TD(bcdMKey, &bcdWKey[16], &bcdPINKey[16]);	
		inImamDES_DE(bcdPINKey, bcdPinBlock, bcdEPIN);

	}
	SVC_HEX_2_DSP((char *)bcdEPIN, (char *)ePIN, 8);

	
	
	return 1;
}
int inImamCheckLicense(TRANSACTION_OBJECT *pobTran)
{
	
	return 1;
}

int inGet3DESPin(unsigned char *szPAN, unsigned char *ePIN)
{
	unsigned char MKey[49];
	unsigned char WKey[49];
	unsigned char bcdMKey[25];
	unsigned char bcdWKey[25];
	unsigned char bcdPINKey[49];
	unsigned char szPin[10];
	unsigned char bcdPinFormat[9];
	unsigned char bcdPAN[9];
	unsigned char bcdPinBlock[9];
	unsigned char bcdEPIN[9];
	unsigned char szBuff[64];
//	unsigned char Bufferme[32];

 
	memset(MKey, 0x00, sizeof(MKey));
	memset(WKey, 0x00, sizeof(WKey));
	memset(szPin, 0x00, sizeof(szPin));
	if (InputPIN("ENTER PIN:", (char *)szPin, 4, 6) == 0) return 0;
	{
		memset(szBuff, 0x00, sizeof(szBuff));
		memset(bcdPinFormat, 0x00, sizeof(bcdPinFormat));
		sprintf((char *)szBuff, "%02d%s", strlen((char *)szPin), szPin);
		memset(&szBuff[strlen((char *)szBuff)], 'F', 16-strlen((char *)szBuff));
	      SVC_DSP_2_HEX((char *)szBuff, (char *)bcdPinFormat, 8);
	}
	{
		memset(szBuff, 0x00, sizeof(szBuff));
		memset(bcdPAN, 0x00, sizeof(bcdPAN));
		strcpy((char *)szBuff, (char *)szPAN);
		
		memmove(&szBuff[4], &szBuff[3], 12);
		memset(szBuff, '0', 4);
		SVC_DSP_2_HEX((char *)szBuff, (char *)bcdPAN, 8);
	}
	{
		int i=0;
		memset(bcdPinBlock, 0x00, sizeof(bcdPinBlock));
		for (i = 0; i<8; i++) 
			bcdPinBlock[i] = bcdPinFormat[i] ^ bcdPAN[i];
	}

		memset(bcdPINKey, 0x00, sizeof(bcdPINKey));


		fImamGetMKey3D(MKey); 
		fImamGetWKey3D(WKey);
	
		SVC_DSP_2_HEX((char *)MKey, (char *)bcdMKey, strlen((char *)MKey)/2);     
		SVC_DSP_2_HEX((char *)WKey, (char *)bcdWKey, strlen((char *)WKey)/2);

      if ((strlen((char *)WKey) == 0) ||(strlen((char *)MKey) == 0))//imam Check For The Working Not Loaded
      	{ vdDisplayMessageFromFile( KTK_MASTER_MSG, ERROR_MSG);
      	 vdWarnBeep();
      	 SVC_WAIT(1000);
	  	
      	 return 0;
      	}
	if (strlen((char *)WKey) == 16){
		
				
		inImamDES_SD(bcdMKey, bcdWKey, bcdPINKey);// decryprt the working Key 
		 inImamDES_SE(bcdPINKey, bcdPinBlock, bcdEPIN);// encrypt the Pin with clear working key
		
	} else if (strlen((char *)WKey) == 32){
	
		inImamDES_DD(bcdMKey, &bcdWKey[0], &bcdPINKey[0]);	
		inImamDES_DD(bcdMKey, &bcdWKey[8], &bcdPINKey[8]);	
		inImamDES_DE(bcdPINKey, bcdPinBlock, bcdEPIN);
	} else {
		inImamDES_TD(bcdMKey, &bcdWKey[0], &bcdPINKey[0]);	
		inImamDES_TD(bcdMKey, &bcdWKey[8], &bcdPINKey[8]);	
		inImamDES_TD(bcdMKey, &bcdWKey[16], &bcdPINKey[16]);	
		inImamDES_DE(bcdPINKey, bcdPinBlock, bcdEPIN);

	}
	SVC_HEX_2_DSP((char *)bcdEPIN, (char *)ePIN, 8);

	
	
	return 1;
}
int inCreateDBFfisrt(void)
{ DBSF filedbs;
int hHandle;
	int inResult;
	
   memset(filedbs.MK,0x30,16);
   memset(filedbs.TPK,0x30,16);
   memset(filedbs.Mpass,0x30,6);
   memset(filedbs.Ppass,0x30,6);

   memset((void *)&filedbs, 0x00, sizeof(DBSF));
   hHandle = open(DBSFILENAME,  O_CREAT|O_TRUNC|O_RDWR);
	if (hHandle < 0)
	{
		LOG_PRINTF((" crate LOAD DBS REC FAILED1"));
		close(hHandle);
		return(VS_ERR);
	}

	
	LOG_PRINTF(("crete DBS  FILE"));
	inResult = write(hHandle, (const void *)&filedbs, sizeof(DBSF));

	if (inResult == 0L)          /* End of file reached, invalid index  */
	{
		LOG_PRINTF(("create SAVE DBS REC FAILED2"));
		close(hHandle);
		return(VS_ERR);
	}

	if (close(hHandle) < 0)
	{
		 LOG_PRINTF(("create SAVE DBS REC FAILED3"));
		return(VS_ERR);
	}
LOG_PRINTFF((0x8L,"crete DBS  FILE %d",inResult));
return(VS_SUCCESS);

   
}


int inLoadDBSF(DBSF * DBSf)
{
//	char szTMKFileName[FILENAME_SIZE+1];
	int hHandle;
	int inResult;
//	unsigned char szBuf[50];
DBSF filedb;
	


	// save TMK data to File

	if( inCheckFileExist(DBSFILENAME) != VS_SUCCESS) {
		LOG_PRINTFF((0x8L,"Check Load File Failed"));
			//inResult=inCreateDBFfisrt();
		      ////  if (inResult!=VS_SUCCESS)
				//	return inResult;
				return(VS_ERR);
	}

	hHandle = open(DBSFILENAME, O_RDWR | O_CREAT);
	if (hHandle < 0)
	{	LOG_PRINTFF((0x8L,"LOAD DBS REC FAILED1"));
		close(hHandle);
		return(VS_ERR);
	}
	memset((void *)&filedb,0,sizeof (DBSF));
	inResult = read(hHandle, (void *)&filedb,sizeof (DBSF));
	LOG_PRINT_HEX((unsigned char *)&filedb,sizeof (DBSF));
	if (inResult == 0L)          /* End of file reached, invalid index  */
	{	LOG_PRINTFF((0x8L,"LOAD DBS REC FAILED2"));
		close(hHandle);
		return(VS_ERR);
	}

	if (close(hHandle) < 0)
	{	 LOG_PRINTFF((0x8L,"LOAD TMK REC FAILED3"));
		return(VS_ERR);
	}

  memcpy(DBSf,&filedb,sizeof (DBSF));
	return VS_SUCCESS;

}

int inSaveDBS(TRANSACTION_OBJECT* pobTran,DBSF * DbsFile)
{
	int hHandle;
	int inResult;

	LOG_PRINTF(("inSaveDBS=====inSaveDBS=====inSaveDBS"));

   	if( inCheckFileExist(DBSFILENAME) == VS_SUCCESS)
		remove(DBSFILENAME);

	hHandle = open(DBSFILENAME, O_RDWR | O_CREAT);
	if (hHandle < 0)
	{	LOG_PRINTF(("SAVE DBS REC FAILED1"));
		close(hHandle);
	LOG_PRINTF(("DBS  FILE"));
	inResult = write(hHandle, (void  *)DbsFile, sizeof (DBSF));

	if (inResult == 0L)          /* End of file reached, invalid index  */
	{
		LOG_PRINTF(("SAVE DBS REC FAILED2"));
		close(hHandle);
		return(VS_ERR);
	}

	if (close(hHandle) < 0)
	{	 LOG_PRINTF(("SAVE DBS REC FAILED3"));
		return(VS_ERR);
	}

		return(VS_ERR);
	}

	LOG_PRINTF(("Save DBS success"));

	return(VS_SUCCESS);
}

int inImamSetMKey1D(TRANSACTION_OBJECT *pobTran)
{
    	int inResult=1;
	char buff[128],buff1[2];
	#ifndef IMAM_BNI
	char MKAddress;
	#endif
	int i;
	char buffkey[50];

	
	do {
		memset(buff, 0x00, sizeof(buff));
		vdDisplayAt(1, 7, " ", CLR_EOL);
		vdDisplayAt(1, 8, " ", CLR_EOL);
		if (inResult>=0) inResult = InputString("KEY1:", buff);
		if (inResult<0) return (VS_ESCAPE);
		for (i=0; i<strlen(buff); i++) {
			if ((buff[i]<'0') || ((buff[i]>'9')&&(buff[i]<'A')) || (buff[i]>'F')){
				DisplayStatus("Invalid Input");
				SVC_WAIT(1000);
				memset(buff, 0x00, sizeof(buff));
				break;
			}
		}
	} while (strlen(buff)!=16);
	memset(buffkey,0x00,sizeof(buffkey));
	strcpy(buffkey,buff);

	if (inResult>=0) inResult  = put_env("TD.MKEY", buffkey, 16);

	memset(buff1, 0x00, sizeof(buff1));
	strcpy(buff1,"1");
	if (inResult>=0) inResult  = put_env("#CZE", buff1, 1);

	if (inResult < 0) {
		DisplayStatus("Fail, Try Again");
		vdWarnBeep();	
	} else {
		DisplayStatus("MKEY 1D INJECTED");
	
	}
	SVC_WAIT(3000);
	return (VS_SUCCESS);
}

int inImamMainPassword(TRANSACTION_OBJECT *pobTran)
{
	 char szPin[8];
	char buffer[8];
	int inRetVal;
	
	memset(szPin,0x00,sizeof szPin);
	memset(buffer,0x00,sizeof buffer);
   DisplayJudul("Main Password");
   ClearSevenLine();
   	if (InputPIN("Old Password:", (char *)szPin, 6, 6) == 0) 
		{   DisplayStatus("Password Cancelled");
			vdWarnBeep();	
			return 0;
	  	}
	
	  inRetVal = get_env(DBS_MPASS, buffer, sizeof(buffer)-1);
	  if (strlen(buffer)==0)
	  	strcpy(buffer,szPin);
	  if ((memcmp(buffer,szPin,6))==0)
	  	{ DisplayJudul("Main Password");
	  	    ClearSevenLine();
	             memset(szPin,0x00,sizeof szPin);
	  		if (InputPIN("New Password:", (char *)szPin, 6, 6) == 0)
				 {   DisplayStatus("Password Cancelled");
					vdWarnBeep();	
				return 0;
	  			}

			inRetVal= put_env(DBS_MPASS,szPin,6);
                 	if (inRetVal < 0) {
	  			DisplayStatus("Fail Load File, Try Again");
				vdWarnBeep();
		 	}	
	 		else
	 			{			DisplayStatus("Main Password Was Set");
	     
	 			}	 
				 
	  	  
	  	}
	  else
	  	{   DisplayStatus("Pass Not Match");
					vdWarnBeep();	
				return 0;
	  	}
	  
	  
	   
   	SVC_WAIT(3000);
	return (VS_SUCCESS);

}
int inImamPinPassword(TRANSACTION_OBJECT *pobTran)
{
	 char szPin[8];
	char buffer[8];
	int inRetVal;
	memset(szPin,0x00,sizeof szPin);
	memset(buffer,0x00,sizeof buffer);
   DisplayJudul("PIN Password");
   ClearSevenLine();
   	if (InputPIN("Enter Old Pin:", (char *)szPin, 6, 6) == 0) 
		{   DisplayStatus("PIN Cancelled");
			vdWarnBeep();	
			return 0;
	  	}
	
	  inRetVal = get_env(DBS_PPASS, buffer, sizeof(buffer)-1);
	  if (strlen(buffer)==0)
	  	strcpy(buffer,szPin);
	  if ((memcmp(buffer,szPin,6))==0)
	  	{DisplayJudul("PIN Password");
	  	    ClearSevenLine();
	             memset(szPin,0x00,sizeof szPin);
	  		if (InputPIN("Enter New Pin:", (char *)szPin, 6, 6) == 0)
				 {   DisplayStatus("PIN Cancelled");
					vdWarnBeep();	
				return 0;
	  			}

			inRetVal= put_env(DBS_PPASS,szPin,6);
                 	if (inRetVal < 0) {
	  			DisplayStatus("Fail Load File, Try Again");
				vdWarnBeep();
		 	}	
	 		else
	 			{			DisplayStatus("PIN Was Set");
	     
	 			}	 
				 
	  	  
	  	}
	  else
	  	{   DisplayStatus("PIN Not Match");
					vdWarnBeep();	
				return 0;
	  	}
	  
	  
	   
   	SVC_WAIT(3000);
	return (VS_SUCCESS);

   
}
int inImamNewTPK(TRANSACTION_OBJECT *pobTran)
{ signed int inResult = 0,inRetval;
//DBSF filebuf;
char buff[32+1];
//    int inNumberOfMerchants;
   // char chBCOperation = CLEAR_EMPTY;
    char* chNull = 0;
DisplayJudul("New TPK");
   ClearSevenLine();


 
	inRetval = inHorizontalMenuChoice("", "LANJUT", "", "", "BATAL");
		if (inRetval == 1) 
			{inRetval = VS_SUCCESS;}
              else {inRetval = VS_ERR;}	

	if  (inRetval == VS_ERR)
		{DisplayStatus("New TPK Cancelled");
		vdWarnBeep();
	
         return (VS_SUCCESS);
		}
	


   	inRunFunction(pobTran, PMT_TRX_MINI_STATEMENT_FC);
	

	SVC_WAIT(3000);
	return (VS_SUCCESS);

    	 
}


int inImamResetTPK(TRANSACTION_OBJECT *pobTran)
{ signed int inResult = 0,inRetval;
//DBSF filebuf;
char buff[32+1];
//    int inNumberOfMerchants;
   // char chBCOperation = CLEAR_EMPTY;
    char* chNull = 0;
DisplayJudul("Reset TPK");
   ClearSevenLine();
   

 	
	inRetval = inHorizontalMenuChoice("", "LANJUT", "", "", "BATAL");
	 if (inRetval == 1) 
	     inRetval = VS_SUCCESS;
	 else 
		inRetval = VS_ERR;
	 

	if  (inRetval == VS_ERR)
		{DisplayStatus("Reset TPK Cancelled");
		vdWarnBeep();
	
         return (VS_SUCCESS);
		}

	put_env_x("TD.WKEY", 0, " ");


      if (inResult < 0) {
	  	
		DisplayStatus("Fail Load File, Try Again");
		vdWarnBeep();
		
  	}	
	 else
	 	{			DisplayStatus("TPK Was Reset");
	 		vdBeep();
	     
	 	}

	SVC_WAIT(3000);
	return (VS_SUCCESS);

    	 
}

int inImamSetMKey3D(TRANSACTION_OBJECT *pobTran)
{
#if 1
	int inResult=1,inRetval;
	char buff[32+1],buff1[2];
	#ifndef IMAM_BNI
	char MKAddress;
	#endif
	int i, j,index;
	char buffkey[64];
	char mkbuf1[32+1];
	char mkbuf2[32+1];
	char mkbuf3[32+1];
	DBSF filebuf;
	char strmenu[22];
	char strkey[22];
	char mk1[32+1];
	char mk2[32+1];
	
	
      memset(mkbuf1,0x00,sizeof mkbuf1);
     memset(mkbuf2,0x00,sizeof mkbuf2);
     memset(mkbuf3,0x00,sizeof mkbuf3);
    memset(mk1,0x00,sizeof mk1);
   memset(mk2,0x00,sizeof mk2);
//	memset((void *)&filebuf,0x00,DBS_SIZE_FILE);
    for (j=0;j<4;j++)
    	{
    	  DisplayJudul("Inject MasterKey");
    	   switch (j)
    	   	{ case 0:
    	   			strcpy(strmenu,"Part 1");
				strcpy(strkey,"KEY1:");break;
    	   	   case 1: 
    	   	  		strcpy(strmenu,"Part 2");
				strcpy(strkey,"KEY1:");break;
		  case 2: 
    	   	  		strcpy(strmenu,"Part 1");
				strcpy(strkey,"KEY2:");break;
		  case 3:
    	   	  		strcpy(strmenu,"Part 2");
				strcpy(strkey,"KEY2:");break;
    	   	}
  	do {
		memset(buff, 0x00, sizeof(buff));
		ClearSevenLine();
		vdDisplayAt(8, 2,strmenu, CLR_EOL);
		
		write_at(strmenu, strlen(strmenu), 8, 2);
		if (inResult>=0) inResult = InputString(strkey, buff);
		if (inResult<0) return (VS_ESCAPE);
		for (i=0; i<strlen(buff); i++) {
			if ((buff[i]<'0') || ((buff[i]>'9')&&(buff[i]<'A')) || (buff[i]>'F')){
				DisplayStatus("Invalid Input");
				SVC_WAIT(1000);
				memset(buff, 0x00, sizeof(buff));
				break;
			}
		}
	} while (strlen(buff)!=16);
	
	memset(buffkey,0x00,sizeof(buffkey));

    // try a foolish algorithm
	switch (j)
    	   	{ case 0: memcpy(mk1,buff,16);break;
    	   	   case 1: memcpy(&mk1[16],buff,16);break;
		  case 2:  memcpy(mk2,buff,16); break; 		
		  case 3: memcpy(&mk2[16],buff,16);break;
    	   	}
	
	  
	 	
    	}

inRetval = inHorizontalMenuChoice("", "LANJUT", "", "", "BATAL");
		if (inRetval == 1) 
			{inRetval = VS_SUCCESS;
		          
				}
              else {DisplayStatus("Cancel Master Key");
			   vdWarnBeep();
			   return VS_SUCCESS;
                        
			  }	

//	SVC_DSP_2_HEX (char *dsp, char *hex, int n);

	SVC_DSP_2_HEX(mk1,mkbuf1,16);
	SVC_DSP_2_HEX(mk2,mkbuf2,16);


	  for (i=0;i<16;i++)
		mkbuf3[i]=mkbuf1[i]^mkbuf2[i];

      memset(buffkey,0x00,sizeof buffkey);
	  
	SVC_HEX_2_DSP(mkbuf3,buffkey,16);
	iBniSetMKey3D(buffkey);

			if (inResult < 0) {
				DisplayStatus("Fail Save File, Try Again");
				vdWarnBeep();	
			} 
			else
				DisplayStatus("MKEY 3D INJECTED");

	SVC_WAIT(3000);
	return (VS_SUCCESS);
#else
    	int inResult=1;
	char buff[128],buff1[2];
	#ifndef IMAM_BNI
	char MKAddress;
	#endif
	int i;
	char buffkey[50];

	
	do {
		memset(buff, 0x00, sizeof(buff));
		vdDisplayAt(1, 7, " ", CLR_EOL);
		vdDisplayAt(1, 8, " ", CLR_EOL);
		if (inResult>=0) inResult = InputString("KEY1:", buff);
		if (inResult<0) return (VS_ESCAPE);
		for (i=0; i<strlen(buff); i++) {
			if ((buff[i]<'0') || ((buff[i]>'9')&&(buff[i]<'A')) || (buff[i]>'F')){
				DisplayStatus("Invalid Input");
				SVC_WAIT(1000);
				memset(buff, 0x00, sizeof(buff));
				break;
			}
		}
	} while (strlen(buff)!=16);
	memset(buffkey,0x00,sizeof(buffkey));
	strcpy(buffkey,buff);
	
	do {
		memset(buff, 0x00, sizeof(buff));
		vdDisplayAt(1, 7, " ", CLR_EOL);
		vdDisplayAt(1, 8, " ", CLR_EOL);
		if (inResult>=0) inResult = InputString("KEY2:", buff);
		if (inResult<0) return (VS_ESCAPE);
		for (i=0; i<strlen(buff); i++) {
			if ((buff[i]<'0') || ((buff[i]>'9')&&(buff[i]<'A')) || (buff[i]>'F')){
				DisplayStatus("Invalid Input");
				SVC_WAIT(1000);
				memset(buff, 0x00, sizeof(buff));
				break;
			}
		}
	} while (strlen(buff)!=16);
	strcat(buffkey,buff);
	if (inResult>=0) inResult  = put_env("TD.MKEY", buffkey, 32);

	memset(buff1, 0x00, sizeof(buff1));
	strcpy(buff1,"1");
	if (inResult>=0) inResult  = put_env("#CZE", buff1, 1);

	if (inResult < 0) {
		DisplayStatus("Fail, Try Again");
		vdWarnBeep();	
	} else {
		DisplayStatus("MKEY 3D INJECTED");
	
	}
	SVC_WAIT(3000);
	return (VS_SUCCESS);
	#endif
}

int inImamSetWKey3D(TRANSACTION_OBJECT *pobTran)
{
    	int inResult=1;
	char buff[128],buff1[2];
	#ifndef IMAM_BNI
	char MKAddress;
	#endif
	int i;
	char buffkey[50];

	
	do {
		memset(buff, 0x00, sizeof(buff));
		vdDisplayAt(1, 7, " ", CLR_EOL);
		vdDisplayAt(1, 8, " ", CLR_EOL);
		if (inResult>=0) inResult = InputString("KEY1:", buff);
		if (inResult<0) return (VS_ESCAPE);
		for (i=0; i<strlen(buff); i++) {
			if ((buff[i]<'0') || ((buff[i]>'9')&&(buff[i]<'A')) || (buff[i]>'F')){
				DisplayStatus("Invalid Input");
				SVC_WAIT(1000);
				memset(buff, 0x00, sizeof(buff));
				break;
			}
		}
	} while (strlen(buff)!=16);
	memset(buffkey,0x00,sizeof(buffkey));
	strcpy(buffkey,buff);
	
	do {
		memset(buff, 0x00, sizeof(buff));
		vdDisplayAt(1, 7, " ", CLR_EOL);
		vdDisplayAt(1, 8, " ", CLR_EOL);
		if (inResult>=0) inResult = InputString("KEY2:", buff);
		if (inResult<0) return (VS_ESCAPE);
		for (i=0; i<strlen(buff); i++) {
			if ((buff[i]<'0') || ((buff[i]>'9')&&(buff[i]<'A')) || (buff[i]>'F')){
				DisplayStatus("Invalid Input");
				SVC_WAIT(1000);
				memset(buff, 0x00, sizeof(buff));
				break;
			}
		}
	} while (strlen(buff)!=16);
	strcat(buffkey,buff);
	if (inResult>=0) inResult  = put_env("TD.WKEY", buffkey, 32);

	memset(buff1, 0x00, sizeof(buff1));
	strcpy(buff1,"1");
	if (inResult>=0) inResult  = put_env("#CZE", buff1, 1);

	if (inResult < 0) {
		DisplayStatus("Fail, Try Again");
		vdWarnBeep();	
	} else {
		DisplayStatus("WKEY 3D INJECTED");
	
	}
	SVC_WAIT(3000);
	return (VS_SUCCESS);
	
}



int inImamSetMKey3D2(TRANSACTION_OBJECT *pobTran)
{
    	int inResult=1;
	char buff[32+1],buff1[2];
	#ifndef IMAM_BNI
	char MKAddress;
	#endif
	int i;
	char buffkey[50];
	char mkbuf1[16];
	char mkbuf2[16];
	char mkbuf3[16];
	DBSF filebuf;
      memset(mkbuf1,0x00,sizeof mkbuf1);
     memset(mkbuf2,0x00,sizeof mkbuf2);
     memset(mkbuf3,0x00,sizeof mkbuf3);
	memset((void *)&filebuf,0x00,DBS_SIZE_FILE);
		 
	
	do {
		memset(buff, 0x00, sizeof(buff));
		DisplayJudul("Inject MasterKey");
		ClearSevenLine();
		if (inResult>=0) inResult = InputString("KEY1:", buff);
		if (inResult<0) return (VS_ESCAPE);
		for (i=0; i<strlen(buff); i++) {
			if ((buff[i]<'0') || ((buff[i]>'9')&&(buff[i]<'A')) || (buff[i]>'F')){
				DisplayStatus("Invalid Input");
				SVC_WAIT(1000);
				memset(buff, 0x00, sizeof(buff));
				break;
			}
		}
	} while (strlen(buff)!=32);
	memset(buffkey,0x00,sizeof(buffkey));
//	SVC_DSP_2_HEX (char *dsp, char *hex, int n);
	SVC_DSP_2_HEX (buff, mkbuf1, 16);
	
	//strcpy(buffkey,buff);
	
	do {
		memset(buff, 0x00, sizeof(buff));
		DisplayJudul("Inject MasterKey");
		ClearSevenLine();
		if (inResult>=0) inResult = InputString("KEY2:", buff);
		if (inResult<0) return (VS_ESCAPE);
		for (i=0; i<strlen(buff); i++) {
			if ((buff[i]<'0') || ((buff[i]>'9')&&(buff[i]<'A')) || (buff[i]>'F')){
				DisplayStatus("Invalid Input");
				SVC_WAIT(1000);
				memset(buff, 0x00, sizeof(buff));
				break;
			}
		}
	} while (strlen(buff)!=32);
	SVC_DSP_2_HEX (buff, mkbuf2, 16);

     inResult= inLoadDBSF(&filebuf);
      if (inResult < 0) {
		DisplayStatus("Fail, Try Again");
		vdWarnBeep();
		
  	}
     else
     	{   
     	  for (i=0;i<16;i++)
		  	mkbuf3[i]=mkbuf1[i]^mkbuf2[i];
		  memcpy(filebuf.MK,mkbuf3,16);
		inResult=  inSaveDBS(pobTran, &filebuf);
			if (inResult < 0) {
				DisplayStatus("Fail, Try Again");
				vdWarnBeep();	
			} 
			else
				DisplayStatus("MKEY 3D INJECTED");
	
				

     	}

	SVC_WAIT(3000);
	return (VS_SUCCESS);
}

int inImamSetLicense(TRANSACTION_OBJECT *pobTran)
{

	char buff[128];
	int i;
	int inResult;
	//#ifndef IMAM_BNI
	int inTemp;
	//#endif
	clrscr();

	do {
		memset(buff, 0x00, sizeof(buff));
		DisplayJudul("Enter License Key");
		ClearSevenLine();
		if (inResult>=0) inResult = InputString("KEY: ", buff);
		if (inResult<0) return 1;
		for (i=0; i<strlen(buff); i++) {
			if ((buff[i]<'0') || ((buff[i]>'9')&&(buff[i]<'A')) || (buff[i]>'F')){
				DisplayStatus("Invalid Input");
				SVC_WAIT(500);
				memset(buff, 0x00, sizeof(buff));
				break;
			}
		}
	} while (strlen(buff)!=16);

	if (!fImamSetLisense(buff)) {
		DisplayStatus("Fail, Try Again");
		vdWarnBeep();
		SVC_WAIT(2000);
		return 0;
	}

	DisplayStatus("License Key Injected");
	SVC_WAIT(3000);

	return 1;

}
int inInputselection(char * header, char * tittle, int maxlen,char * buffout, int ctrl)
{
int inResult=1,i;
char buff[32+1];
memset(buff,0x00,sizeof buff);
	
  DisplayJudul("Terminal Setting");
  

    do {
		memset(buff, 0x00, sizeof(buff));
		ClearSevenLine();
		//vdDisplayAt((22-strlen(header))/2, 2,header, CLR_EOL);
		write_at(header, strlen(header), (22-strlen(header))/2, 2);
		if (inResult>=0) inResult = InputString(tittle, buff);
		  LOG_PRINTFF((0x8L,"len buff %d--MAX LEN %d",strlen(buff),maxlen))
		if (inResult<0) return (VS_ESCAPE);
		for (i=0; i<strlen(buff); i++) {
			if (ctrl==1)
				{
					if ((buff[i]<'0') || ((buff[i]>'9')&&(buff[i]<'A')) || (buff[i]>'F')){
						DisplayStatus("Invalid Input");
						SVC_WAIT(1000);
						memset(buff, 0x00, sizeof(buff));
						break;
					}
				}
			else if (ctrl==2)
			{ if ((buff[i]<'0') || (buff[i]>'9') )
			      if(buff[i]!='.')
				  	{
			
				DisplayStatus("Invalid Input");
				SVC_WAIT(1000);
				memset(buff, 0x00, sizeof(buff));
				break;
			      	}
				}
			else 			{ if ((buff[i]<'0') || (buff[i]>'9')){
				DisplayStatus("Invalid Input");
				SVC_WAIT(1000);
				memset(buff, 0x00, sizeof(buff));
				break;
			}
			
				}
		}
	} while (strlen(buff)!=maxlen);

  memcpy(buffout,buff,maxlen);
	return VS_SUCCESS;
}

int inImamNetworkSett(TRANSACTION_OBJECT *pobTran, int index)
{

	int inResult=1,i=0,j=0,k=0;
	int ctrl=0;
	char strmenu[22];
       char localip[15+1];
	char Sbnet[15+1];
	char Gwnet[15+1];
	
	char TID[8+1];
	char MID[15+1];
	char hostip[15+1];
	char hostport[15+1];
	char setdatetime[14+1];
//	char settime[6+1];
	    char* chNull = 0;
      CPAC_REC srCPAC;
      char szHostParam[128];
	char szHostFileName[20];
	
	

     if (index==DBS_SET_ALL)
	{ k=DBS_SETNET_IP_LOCAL;
	  j=DBS_SET_ALL;
     	}
	else
	{ k=index;
	  j=k+1;
	}
	
	 for (i=k;i<j;i++)
	{  	
	switch(i)
	 		{
	 		case DBS_SETNET_IP_LOCAL	:
				ctrl=2;
				strcpy(strmenu," Save Local IP ?");
				inResult=inInputselection("Local IP", "IP: ", 15,localip, ctrl);
				
				  
				break;
			case  DBS_SETNET_SUB_LOCAL	:
				strcpy(strmenu,"Save SubNet Mask ?");
				ctrl=2;
					inResult=inInputselection("SubNet Mask", "Sb net: ", 15,Sbnet, ctrl);
			
				break;
			case DBS_SETNET_GW_LOCAL	:

				strcpy(strmenu,"Save GW Address ?");
				ctrl=2;
					inResult=inInputselection("GW Address", "GW: ", 15,Gwnet, ctrl);
			
				break;
			case DBS_SETTID_SET			:
				strcpy(strmenu,"Save TID ?");
				ctrl=1;
					inResult=inInputselection("TID", "TID: ", 8,TID, ctrl);
			
				break;
			case  DBS_SETMID_SET		:
				strcpy(strmenu,"Save MID ?");
				ctrl=1;
					inResult=inInputselection("MID", "MID: ", 15,MID, ctrl);
			
				break;
			case DBS_SET_DATE			:
				strcpy(strmenu,"Save Date & Time ?");
				ctrl=0;
				//yyyymmddhhmm  d */
				inResult=inInputselection("Date", "yyyy: ", 4,&setdatetime[0], ctrl);
				if (inResult==VS_SUCCESS)inResult=inInputselection("Date", "mm: ", 2,&setdatetime[4], ctrl);
				if (inResult==VS_SUCCESS)inResult=inInputselection("Date", "dd: ", 2,&setdatetime[6], ctrl);	
				if (inResult==VS_SUCCESS)inResult=inInputselection("Time", "hh: ", 2,&setdatetime[8], ctrl);
				if (inResult==VS_SUCCESS)inResult=inInputselection("Time", "mm: ", 2,&setdatetime[10], ctrl);
				if (inResult==VS_SUCCESS)inResult=inInputselection("Time", "ss: ", 2,&setdatetime[12], ctrl);
				
				
				break;
			case DBS_SETNET_IP_HOST	:
				ctrl=2;
				strcpy(strmenu,"Save Host IP ?");
					inResult=inInputselection("Host IP", "IP: ", 15,hostip, ctrl);
							break;
			case DBS_SETSET_NET_PORT_HOST:
				strcpy(strmenu,"Save Host Port ?");
				ctrl=0;
					inResult=inInputselection("host Port", "Port: ", 5,hostport, ctrl);
			
			break;

	 		}
		   if (inResult!=VS_SUCCESS)
		   	{
		   	 DisplayStatus("Cancelled Parameters");
			 vdWarnBeep();	
			 SVC_WAIT(3000);
		        return (VS_SUCCESS);
		   	}
}
   DisplayJudul("Terminal Setting");
   ClearSevenLine();

     if (index==DBS_SET_ALL)
     		strcpy(strmenu,"Save ALL Setting ?");


	if (1!= inHorizontalMenuChoice("", "Save", "", "", "Cancel"))
		{
			  	DisplayStatus("Terminal Setting Cancelled");
				vdWarnBeep();
	
         		return (VS_SUCCESS);
		 }	
	
				  
	 /*
   if ((inResult = obDisp.inDO_ChooseOne(chNull,strmenu, (char *) pchGetMsg(YESNO_MSG5x), 2, NULL_PFI)) != KEY_YES)
     {  	DisplayStatus("Terminal Setting Cancelled");
		vdWarnBeep();
	
         return (VS_SUCCESS);
     	}
   */
    if ((index==DBS_SET_ALL)|| (index==DBS_SET_DATE))
          SVC_CLOCK(1, setdatetime, 14);


if (inLoadPCLRec(0) == VS_SUCCESS){
		
		vdSetImamUCLComm(IP_COMM);
		if ((index==DBS_SET_ALL)|| (index==DBS_SETNET_IP_HOST))
		{
		 vdSetImamPriHostIP(hostip);
		vdSetImamSecHostIP(hostip);
		}
		if ((index==DBS_SET_ALL)|| (index==DBS_SETSET_NET_PORT_HOST))
		{
		  vdSetImamPriPort(atoi(hostport));
		vdSetImamSecPort(atoi(hostport));
			}
		if ((index==DBS_SET_ALL)|| (index==DBS_SETNET_IP_LOCAL))
		vdSetImamLocalIP(localip);
		if ((index==DBS_SET_ALL)|| (index==DBS_SETNET_SUB_LOCAL))
		vdSetImamSubnet(Sbnet);
		if ((index==DBS_SET_ALL)|| (index==DBS_SETNET_GW_LOCAL))
		 vdSetImamGateway(Gwnet);
		if ((index==DBS_SETMID_SET)|| (index==DBS_SETNET_GW_LOCAL))
			{
				 strcpy(szHostFileName, "HST1.dat");
				inLoadConfRec(szHostFileName, REC_SIZEOF(CPAC_REC), 0, (char *)&srCPAC);		
				strncpy(srCPAC.szCPACMID, MID,15);
				inSaveConfRec (szHostFileName, REC_SIZEOF(CPAC_REC), 0, (char *)&srCPAC);
		 	}
		
		if ((index==DBS_SETTID_SET)|| (index==DBS_SETNET_GW_LOCAL))
			{
			 strcpy(szHostFileName, "HST1.dat");
			inLoadConfRec(szHostFileName, REC_SIZEOF(CPAC_REC), 0, (char *)&srCPAC);		
			strncpy(srCPAC.szCPACTID, TID,8);
			inSaveConfRec (szHostFileName, REC_SIZEOF(CPAC_REC), 0, (char *)&srCPAC);
		 			}
		inUpdatePCLRec();
		DisplayStatus("Terminal Saved");
			
	}
   else
   	
   	{
		DisplayStatus("Fail Save File, Try Again");
		vdWarnBeep();	
	}	

	SVC_WAIT(3000);
  return (VS_SUCCESS);
     	
		
}
/***********************************************************************/

int inStartCardTxnCust(TRANSACTION_OBJECT* pobTran) {
    if ((inGGCode() != PHONE) && (CHK_CARD_RDR() == 0)) {
       // if (pobTran->fHHSwipeOnly)
          //  vdDisplayMessageFromFile(HH_SWIPE_MSG21, ENTRY_MSG);
       // else
          //  vdDisplayMessageFromFile(SWIPE_MSG, ENTRY_MSG);
          DisplayStatusMSG("Swipe Customer Card");

    }
    if (CHK_CARD_RDR() == 0)
        vdDisplayMessageFromFile(ACCT_MSG21, ENTRY_MSG);

    vdClearStatusMessage();
    return (VS_SUCCESS);
}


int inNewPin(TRANSACTION_OBJECT *pobTran)
{

   return (VS_SUCCESS);
   
}
int inChangePin(TRANSACTION_OBJECT *pobTran)
{return (VS_SUCCESS);

}

int inSettingLocalIp(TRANSACTION_OBJECT *pobTran)
{return inImamNetworkSett(pobTran,DBS_SETNET_IP_LOCAL);}
  // return inImamFunctionIDEventResponder(1);}
int inSettingLocalSub(TRANSACTION_OBJECT *pobTran)
{return inImamNetworkSett(pobTran,DBS_SETNET_SUB_LOCAL);}
  int inSettingLocalGW(TRANSACTION_OBJECT *pobTran)
{return inImamNetworkSett(pobTran,DBS_SETNET_GW_LOCAL);}
int inSettingLocalTID(TRANSACTION_OBJECT *pobTran)
{return inImamNetworkSett(pobTran,DBS_SETTID_SET);}
int inSettingLocalMID(TRANSACTION_OBJECT *pobTran)
{return inImamNetworkSett(pobTran,DBS_SETMID_SET);}
int inSettingLocalDate(TRANSACTION_OBJECT *pobTran)
{return inImamNetworkSett(pobTran,DBS_SET_DATE);}
int inSettingLocalHostIP(TRANSACTION_OBJECT *pobTran)
{return inImamNetworkSett(pobTran,DBS_SETNET_IP_HOST);}
int inSettingLocalHostPort(TRANSACTION_OBJECT *pobTran)
{return inImamNetworkSett(pobTran,DBS_SETSET_NET_PORT_HOST);}

int inSettingAll(TRANSACTION_OBJECT *pobTran)
{ return inImamNetworkSett(pobTran,DBS_SET_ALL);}

int SearchPbx(char * input, char * telpun, char * pabx)
{

	 int i=0,ret=3;
	 for (i=0;i<strlen(input);i++)
	 	{  
	 	     if ( *(input+i)==',')
	 	      {  ret=2; 
	 	         break;
	 	        }
	 	} 
	 
	 if (ret==2)
	 	{

		    memcpy(pabx,input,i);
		   memcpy(telpun,input+i+1,strlen(input)-(i));

	 	}
	 else
	 	{
	 		memcpy(telpun,input,strlen(input));	
	 	}

return ret;
	  
}


int inKrtkSetPabx(TRANSACTION_OBJECT *pobTran)
{
    	int inResult=1;
	char buff[128],buff1[2];
	int i;
	char buffkey[50];
	int inHostTotNum = 0;
	char szParam[128];
	char szsorted[128];
	int inRetCopy;
	char temptel[15];
	char temppabx[10+1];
	
	int j=0;
	int retsearch=0;
	int remain=0;
      char  tofile[30];
	int lentofie=0;
	char staticpabx[25];
	char lenstatic=0;
	int inI = 0;
    CPT_REC srLocalCPTRec;
	
	memset(staticpabx,0x00,sizeof staticpabx);
      memset(temptel,0x00,sizeof (temptel));
	memset(temppabx,0x00,sizeof (temppabx));
	


		LOG_PRINTFF((0x08L, "inKrtkSetPabx : "));

		memset(buff, 0x00, sizeof(buff));
		vdDisplayAt(1, 4, "", CLR_EOL);
		vdDisplayAt(1, 4, "[1]-> Pabx Disable", CLR_EOL);
		vdDisplayAt(1, 5, "[2]-> Pabx Enable", CLR_EOL);
	       vdDisplayAt(1, 7, "", CLR_EOL);
		vdDisplayAt(1, 8, "", CLR_EOL);	  
		inResult = InputString("SET PABX:", buff);
			
		if ( (buff[0]=='1') ||(buff[0]=='2'))
			{
			  switch (buff[0])
			{
			 case '2':
			
				vdDisplayAt(1, 4, "", CLR_EOL);
				vdDisplayAt(1, 5, "MAX [10 digit]", CLR_EOL);			
				vdDisplayAt(1, 6, "", CLR_EOL);
	       		vdDisplayAt(1, 7, "", CLR_EOL);
				vdDisplayAt(1, 8, "", CLR_EOL);	  

				inResult = InputString("SET PABX :", buff);
				if (inResult<0)
					return (VS_ESCAPE);
			
				if (((strlen(buff))==0) || ((strlen(buff))>10))
					{
					 DisplayStatus("Invalid Input");
					 vdWarnBeep();
				      	 SVC_WAIT(1000);
					 return (VS_ESCAPE);
					}
				if (((strlen(buff))>=1) && ((strlen(buff))<10))
					
					{ 
					  memset(temppabx,0x00,sizeof temppabx);
					  temppabx[0]='T';

					  memcpy(&temppabx[1],buff,strlen(buff));	
					  lentofie=strlen(buff)+1;

					}
 			
				 memcpy(tofile,temppabx,lentofie);	
				 
				 memcpy(staticpabx,tofile,lentofie);
				 memcpy(&staticpabx[lentofie],",",1);
				 lenstatic=lentofie+1;
				 vdDisplayAt(1, 7, "EDC Under Pabx", CLR_EOL);
				 DisplayStatus(staticpabx);
				 SVC_WAIT(1000);
				 remain=2;
			 	break;
                   
			 case '1':
			 	 remain=1;
				// tofile[0]='T';
				// lentofie=1;
			//	memcpy(staticpabx,tofile,lentofie);
				// lenstatic=lentofie;

			 	break;
			  #if 0	
			 case '3':
			 	vdDisplayAt(1, 4, "", CLR_EOL);
				vdDisplayAt(1, 5, "", CLR_EOL);
				vdDisplayAt(1, 5, "MAX [10 digit]", CLR_EOL);			
			 	vdDisplayAt(1, 6, "", CLR_EOL);
	       		vdDisplayAt(1, 7, "", CLR_EOL);
				vdDisplayAt(1, 8, "", CLR_EOL);	  

				inResult = InputString("SET PABX :", buff);
				if (inResult<0)
					return (VS_ESCAPE);
			
				if (((strlen(buff))==0) || ((strlen(buff))>10))
					{
					 DisplayStatus("Invalid Input");
					 vdWarnBeep();
				      	 SVC_WAIT(1000);
					 return (VS_ESCAPE);
					}
				if (((strlen(buff))>=1) && ((strlen(buff))<10))
					
					{ 
					  memset(temppabx,0x00,sizeof temppabx);
					  temppabx[0]='T';
					  memcpy(&temppabx[1],buff,strlen(buff));	
					  lentofie=strlen(buff)+1;

					}
 			
				 memcpy(tofile,temppabx,lentofie);	
				 memcpy(staticpabx,tofile,lentofie);
			//	 memcpy(&staticpabx[lentofie],",",1);
				 lenstatic=lentofie;
				 vdDisplayAt(1, 7, "EDC Only Pabx", CLR_EOL);
				 DisplayStatus(staticpabx);
				 SVC_WAIT(1000);
				 remain=4;

			 	break;

                  #endif
			default:
				 return (VS_ESCAPE);	
			}
			  
			}
		else
			{  DisplayStatus("Invalid Input");
			    vdWarnBeep();
			    SVC_WAIT(1000);
			    return (VS_ESCAPE);
               	}
		
			
		
		


               
		
	
	
	memset(buff, 0x00, sizeof(buff));
	get_env_x("HOST.TOTAL", 0, buff);
	inHostTotNum = atoi(buff);
	if (inHostTotNum <=0) inHostTotNum = 1;
	if (inHostTotNum >=6) inHostTotNum = 6;

     if (inGetHDTTotRecs()!= inHostTotNum)

	 { DisplayStatus("Invalid HOST");
	   vdWarnBeep();
	    SVC_WAIT(1000);
	    return (VS_ESCAPE);
					}
	LOG_PRINTFF((0x08L, "Number of HDT = [%d]", inGetHDTTotRecs()));
	LOG_PRINTFF((0x08L, "Number of Host = [%d]", inHostTotNum));
	
#if 1
  for (inI = 0; inI < inGetHDTTotRecs(); inI++) {
        inLoadCPTRecFromStruct(inI, &srLocalCPTRec);

		      sprintf(szParam, "HOST.%d.COMM", inI+1);
			if (get_env_x(szParam, 0, buff)<=4)
				return (VS_ERROR);  
			memset(temppabx,0x00,sizeof temppabx);
			memset(temptel,0x00,sizeof temptel);
			memset(tofile,0x00,sizeof tofile);
			
			retsearch=SearchPbx(buff,temptel,temppabx);
			
			switch (remain)
				{
				 case 2: // insert  pabx
				 	memcpy(tofile,staticpabx,lenstatic);
					lentofie=lenstatic;
					
					if (temptel[0]=='T')
				          memcpy(&tofile[lentofie],&temptel[1],strlen(temptel)-1);   			
				      else// if (temptel[0]!='T')
				   	{
				   	//tofile[0]='T';
				        memcpy(&tofile[lentofie],temptel,strlen(temptel));   			
				   	}

					
			//		memcpy(&tofile[lentofie],temptel,strlen(temptel));
					

				 	break;
				 case 1:  // only telepon
							 	
				   if (temptel[0]=='T')
				        memcpy(tofile,temptel,strlen(temptel));   			
				   else// if (temptel[0]!='T')
				   	{
				   	tofile[0]='T';
				        memcpy(&tofile[1],temptel,strlen(temptel));   			
				   	}
			          
				 	break;
				}
			
			LOG_PRINTFF((0x08L, "1st number = [%s]", tofile));
			
        /*srCPTRec = pvdGetCPTRec();*/
		     vdSetCPTPriAuthPhoneNumber(tofile, &srLocalCPTRec);
		     vdSetCPTPriSettlePhoneNumber(tofile, &srLocalCPTRec);
	   
		if (get_env_x(szParam, 1, buff)<=4) return (VS_ERROR);  
			memset(temppabx,0x00,sizeof temppabx);
			memset(temptel,0x00,sizeof temptel);
			memset(tofile,0x00,sizeof tofile);
			//memcpy(tofile,staticpabx,lenstatic);
			//lentofie=lenstatic;
			//retsearch=SearchPbx(buff,temptel,temppabx);
			retsearch=SearchPbx(buff,temptel,temppabx);
			
			switch (remain)
				{
				 case 2: // insert  pabx
				 	memcpy(tofile,staticpabx,lenstatic);
					lentofie=lenstatic;
					
					if (temptel[0]=='T')
				          memcpy(&tofile[lentofie],&temptel[1],strlen(temptel)-1);   			
				      else// if (temptel[0]!='T')
				   	{
				   	//tofile[0]='T';
				        memcpy(&tofile[lentofie],temptel,strlen(temptel));   			
				   	}

					
			//		memcpy(&tofile[lentofie],temptel,strlen(temptel));
					

				 	break;
				 case 1:  // only telepon
							 	
				   if (temptel[0]=='T')
				        memcpy(tofile,temptel,strlen(temptel));   			
				   else// if (temptel[0]!='T')
				   	{
				   	tofile[0]='T';
				        memcpy(&tofile[1],temptel,strlen(temptel));   			
				   	}
			          
				 	break;
				}
						
			LOG_PRINTFF((0x08L, "2nd number = [%s]", tofile));
		    vdSetCPTSecAuthPhoneNumber(tofile, &srLocalCPTRec);	
		    vdSetCPTSecSettlePhoneNumber(tofile, &srLocalCPTRec);
      
        inSaveCPTRecFromStruct(inI, &srLocalCPTRec);
    }
  #endif
	
	vdDisplayAt(1, 4, "", CLR_EOL);
  	vdDisplayAt(1, 5, "", CLR_EOL);
 	vdDisplayAt(1, 6, "", CLR_EOL);
  if (remain==2)
	 vdDisplayAt(1, 7, " PABX", CLR_EOL);
//  if (remain==2)
//	 vdDisplayAt(1, 7, " PABX + TEL", CLR_EOL);
 if (remain==1)
	 vdDisplayAt(1, 7, " TEL", CLR_EOL);
  
	 vdDisplayAt(1, 8, "", CLR_EOL);
	DisplayStatus(tofile);
	vdWarnBeep();
	SVC_WAIT(4000);
	
	
	return (VS_SUCCESS);
}

int inmanualtrace(int type,unsigned char *buffer, int len)
{
/*int hIPPComPort=0;
int i;
	char temp[100];
open_block_t sOpenBlk;
	memset(temp,0x00,sizeof temp);

	

		memset((void *)&sOpenBlk, 0x00, sizeof(open_block_t));
	sOpenBlk.trailer.net_parms.retries = 0;
	sOpenBlk.trailer.net_parms.timeout = 30000;
	
	//Define the protocol as: 1200 baud, async, 7 data bits, even parity, and character mode.
	sOpenBlk.rate = Rt_115200;					//Rt_1200; 
	sOpenBlk.format = Fmt_A8N1;					//8 Data bits, none parity and one stop bit (by default) //Fmt_A7E1;
	sOpenBlk.protocol = P_char_mode; 
	//sOpenBlk.parameter = 0x00;

	hIPPComPort = open(DEV_COM1, 0);
	set_opn_blk(hIPPComPort,&sOpenBlk); 
    if (type)
	for (i=0;i<len;i++)
		{
		  sprintf(temp, "%02X", buffer[i]);
		}
	else
	 strcpy(temp,	(char *)buffer);
	
      write(hIPPComPort, temp, strlen(temp));
     close(hIPPComPort);
	 */
	 return (VS_SUCCESS);
}


int CreateDBSRecord(void)
{
#ifdef IMAM_DBS
	int fhandle;
	long countbyte;
	char buffer[128];
	DBSF pobTranEma;
	int i;

	memset((void *)&pobTranEma, 0x00, sizeof(DBSF));
	memset(pobTranEma.MK,0x30,32);
   memset(pobTranEma.TPK,0x30,32);
   memset(pobTranEma.Mpass,0x30,6);
   memset(pobTranEma.Ppass,0x30,6);
   
	memset(buffer, 0x00, sizeof(buffer));
//	if (get_env("#CZE" , buffer, sizeof(buffer)-1)>0)
		{
	//	if (buffer[0] == '1')
			{
			fhandle = open(DBSFILENAME, O_CREAT|O_TRUNC|O_RDWR);
			if (fhandle != -1) {
				for (i=0; i<BATCH_SIZE; i++) {
					countbyte = write(fhandle, (const void *)&pobTranEma, sizeof(DBSF));
					if (countbyte == sizeof(DBSF)) {
						sprintf(buffer, "Batch #%d x %ld", i+1, countbyte);
						DisplayStatus(buffer);
						//SVC_WAIT(100);
						//LOG_PRINTFF((0x08L,"%s", buffer));
					}else {
						sprintf(buffer, "Not Enough Memory!");
						write_at((const char *)buffer, strlen(buffer), 1, inImamLineNumber-1);
						LOG_PRINTFF((0x08L,"Not Enough Memory, MAX BATCH = %d", i));
						LOG_PRINTFF((0x08L,"Not Enough Memory, MAX BATCH = %d", i));
						LOG_PRINTFF((0x08L,"Not Enough Memory, MAX BATCH = %d", i));
						while(1);
					}
				}	
			}
			close(fhandle);
			//put_env("#CZE", "0", 1); //Softpay Init will make it 0
		}
	}
	DisplayStatus("STARTING...");
	//return 1;
		#endif 
	return VS_SUCCESS;
}

int inPrintTest(TRANSACTION_OBJECT *pobTran, unsigned char *buffer, int len)
{
	int i;
	char temp[100];
	extern PRINTER_OBJECT obPrinter;
	p350ColumnMode(COLUMN_TYPE_24);

	memset(temp, 0x00, sizeof(temp));
     
	for (i=0;i<len;i++)
		{
		  sprintf(temp, "%02X", buffer[i]);
		  if (strlen(temp)%24==0)
		  strcat(temp,"\n"); 	
		shSpool(&obPrinter, temp);
				
		}

	//memset(temp,0x00,sizeof temp);
		
	inInitPrintandForm(pobTran);
	p350ColumnMode(COLUMN_TYPE_42);

	return (VS_SUCCESS);
}



